Introduction
This is a curated dataset containing the Africa, Brazil, India, and the G6 datasets, which are all TB datasets with active TB patients, patients that will progress to active TB, and people with TB infection who don’t progress. There is a batch effect especially with the Brazil data. This object is a SummarizedExperiment with 7 assays. The ‘combat’ assay was made by running the logtpm values through combat with ‘SequencingBatch’ as the batch and ‘Label’ as the covariate. “Label” is the condition Non-progressor, Progressor, and Active.
Overall design
The combined dataset contains 4 studies, in which Brazil dataset has 2 batches within the study:
- Africa: 197 samples, (104 Non-progressor, 77 Progressor, 16 Active)
- Brazil: 51 samples, (21 Non-progressor, 16 Progressor, 14 Active)
- Batch 1: 39 samples, (9 Non-progressor, 16 Progressor, 14 Active)
- Batch 2: 12 samples, (12 Non-progressor, 0 Progressor, 0 Active)
- G6: 399 samples, (304 Non-progressor, 95 Progressor, 0 Active)
- India: 44 samples, (19 Non-progressor, 0 Progressor, 25 Active)
Note: Gender is an important factor in this study.
Load data & summarize basic info
After loading the data, we calculate a few basic statistics of the dataset.
###### Samples #######
- Total number of samples:
[1] 691
- Number of samples in condition groups:
group
Non-progressor Progressor Active
448 188 55
- Number of samples in batches:
batch
Africa Brazil_1 Brazil_2 G6 India
197 39 12 399 44
In each batch separately:
Non-progressor Progressor Active
Africa 104 77 16
Brazil_1 9 16 14
Brazil_2 12 0 0
G6 304 95 0
India 19 0 25
###### Genes #######
- Total number of genes:
[1] 24391
- Number of genes with 0 counts:
14504 59.5%
- Number of genes with maximum 10 counts:
2587 10.6%
- Number of genes with ONLY 0s:
0 0%
###### Counts #######
- Range of count in whole dataset:
[1] 0 7674206
- Average count in whole dataset:
[1] "Mean: 2350.9"
[1] "Median: 75"
There are no genes with only zero values across all samples (probably because of cleaning in the curation stage). The figure below shows distribution of percentages of zero counts for the remaining genes (each data point represents a gene, i.e., how many zeros are there in each gene).
###### Proportion of genes with X% zeros across samples #######
<10.0% <20.0% <30.0% <40.0% <50.0% <60.0% <70.0% <80.0% <90.0% <100.0%
0.646 0.033 0.023 0.020 0.020 0.021 0.025 0.029 0.045 0.139

Existence of batch effect
In this merged dataset, there are both “study effects” across the 4 studies (targeting different populations), and batch effect within the same study (Brazil dataset).
PCA

PCA (Brazil only)

Dendrograms (Brazil only)

Library size
Next, we take a look at the observed library sizes of samples, and to see if there is a difference in library size across batches.
Range of observed library sizes across samples:
[1] "4.91e+05" "1.09e+08"

Gene expression distribution
Our next step is to interrogate the gene expression distributions.
Fold changes in mean
We use edgeR to perform differential expression analysis, and calculate (log-) fold changes of all genes between condition groups and batches.
Change WRT condition
To rule out the impact of batch effect, we limit our DE analysis with regard to biological condition in one of the batches. Here we specify the batch to be G6 due to a larger batch size, and evaluate DE between progressors and non-progressors.
#### Differential genes relative to biological condition
#### (within batch 1 / batch specified by 'test_batch')
test_batch <- "G6"
counts_batch <- assay(rds_obj,"counts")[, batch==test_batch]
cond_batch <- as.factor(as.character(group[batch==test_batch]))
y <- DGEList(counts=counts_batch, group=as.factor(cond_batch))
y <- calcNormFactors(y, method="TMM")
design <- model.matrix(~as.factor(cond_batch))
y <- estimateDisp(y, design)
###### Changes in terms of average gene counts ######
top50 up top50 down 100 least DE
Non-progressor 1728.5 3362.2 757.1
Progressor 3117.4 2773.3 706.5
###### Range of fold change across biological conditions ######
top50 up top50 down 100 least DE
min FC 1.501 0.004 0.934
median FC 3.975 0.705 1.000
mean FC 21.299 0.563 0.998
max FC 668.720 0.899 1.000
###### Range of Log(fold change) across biological conditions ######
top50 up top50 down 100 least DE
min logFC 0.406 -5.553 -0.068
median logFC 1.380 -0.350 0.000
mean logFC 3.059 -0.574 -0.002
max logFC 6.505 -0.107 0.000

Conclusions:
- Biological fold change comparing average counts in top DE genes is about 1.2-1.8.
- Gene-wise fold change in top DE genes has a wide range (median 4, mean 21).
Change WRT batch
We are also interested to see how the average (mean) gene counts change across batches (i.e. degree of mean batch effect).
To explore this mean batch effect, we first perform DE with regard to the batch variable. To rule out the impact of biological condition, we perform this analysis within Non-progressors only, and compare Africa & G6 studies. Note that this DE is not true DE - it’s testing if there is a significant mean difference between two batches.
#### Differential genes relative to batch
#### (within condition 0 / condition specified by 'test_cond')
rds_subset <- rds_obj[, rds_obj$Dataset %in% c("Africa", "G6")]
test_cond <- "Non-progressor"
counts_cond <- assay(rds_subset, "counts")[, rds_subset$Label==test_cond]
batch_cond <- as.factor(as.character(rds_subset$SequencingBatch[rds_subset$Label==test_cond]))
y <- DGEList(counts=counts_cond, group=as.factor(batch_cond))
y <- calcNormFactors(y, method="TMM")
design <- model.matrix(~as.factor(batch_cond))
y <- estimateDisp(y, design)
fit <- glmQLFit(y, design)
qlf <- glmQLFTest(fit, coef=2)
de_res <- topTags(qlf, n=nrow(rds_subset))
up_genes <- rownames(de_res)[de_res$table$logFC >= 0] # all up-regulated genes
head_up_genes <- head(up_genes, n=50) # top-50 up-regulated genes
tail_up_genes <- tail(up_genes, n=50) # 50 least up-regulated genes
batch_up_inds <- up_genes
down_genes <- rownames(de_res)[de_res$table$logFC < 0] # all down-regulated genes
head_down_genes <- head(down_genes, n=50) # top-50 down-regulated genes
tail_down_genes <- tail(down_genes, n=50) # 50 least down-regulated genes
batch_down_inds <- down_genes
###### Batch differences in terms of mean gene counts ######
top50 up top50 down 100 least changed
Africa 1917.33 4100.75 96.39
G6 6824.55 3466.82 142.55
###### Range of fold change between batches ######
- All genes - FC:
0.005 1291.191
- All genes - log(FC):
-5.352 7.163
- Top genes - FC:
top50 up top50 down 100 least DE
min FC 1.872 0.005 0.953
median FC 4.424 0.425 1.000
mean FC 52.612 0.410 0.996
max FC 1291.191 0.609 1.000
- Top genes - log(FC):
top50 up top50 down 100 least DE
min logFC 0.627 -5.352 -0.049
median logFC 1.487 -0.856 0.000
mean logFC 3.963 -0.892 -0.004
max logFC 7.163 -0.496 0.000
Conclusions:
- Mean batch effect fold change comparing average counts in top genes ranges from 1.18-3.56. Remember that these are genes most significantly different across batch.
- Gene-wise mean batch effect fold change in top genes has a wide range (mean 4.4, median 52.6).
Batch mean
Median (of all genes) gene-wise mean:
Africa G6 Brazil1
Non-progressor 87.85 129.77 15.00
Progressor 74.19 119.88 22.75
Scaled by that of Africa:
Africa G6 Brazil1
Non-progressor 1 1.48 0.17
Progressor 1 1.62 0.31
Batch dispersion
Aside from average gene counts, we are interested in comparing dispersions in the batches. Difference in the dispersions across batches suggests variance batch effect not accounted for by Poisson model. We visualize the gene-wise dispersion estimates from edgeR:
Design matrix not provided. Switch to the classic mode.
#### Statistics about dispersion estimates from the two batches ####
Africa G6 India Brazil_1 Brazil_2
min disp. 0.0054 0.0034 0.0001 0.0390 0.0305
median disp. 0.1916 0.2422 0.1616 0.6837 0.2086
mean disp. 3.3203 2.7797 0.3211 3.0653 0.4466
max disp. 102.4000 102.4000 50.4797 38.5716 6.2874

Conclusions:
- Mean dispersion in the Africa / Batch 1 in the Brazil study is about 10 times of those in the India study.
- We see huge max gene-wise dispersions, possibly caused by 0 counts.
Batch variance
Median (of all genes) gene-wise variance:
Africa G6 Brazil1
Non-progressor 1967.72 4722.60 135.19
Progressor 1620.59 4623.17 469.53
Scaled by that of Africa:
Africa G6 Brazil1
Non-progressor 1 2.40 0.07
Progressor 1 2.85 0.29
Impact of 0 counts on gene distributions
We have seen above that over half of genes in the dataset contain some portions of zeros. Having 0 counts can have a good impact on mean and dispersion estimation. We evaluate such impact in this section, and see how NB distribution fits to non-zero portion of genes. We first take the non-zero portion of the genes.
Fold change in mean in non-zero portion
Change WRT condition in G6
Within G6, we compare mean (here refers to non-zero mean) across biological condition groups. Specifically, we saved the previous DE analysis results using edgeR, on counts containing zeros. We call all genes with \(\log(FC) >= 0\) as “up” genes, and \(\log(FC) < 0\) as “down” genes. The top 50 “up” and “down” genes are still determined by the previous DE containing zeros.
###### Changes in MEAN non-zero gene counts ######
top50 up top50 down 100 least DE
Non-progressor 2169.9 4497.1 2196.1
Progressor 3914.2 3786.5 2085.1
###### Changes in MEDIAN non-zero gene counts ######
top50 up top50 down 100 least DE
Non-progressor 609 2236 474.5
Progressor 961 1834 471.0
Conclusions:
- Biological fold change (in non-zero portion) comparing average counts in top genes is about 1.2-1.8 (mean).
- O counts did not strongly affect biological signal in terms of average counts in top genes .
Change WRT batch in non-progressors
Similarly, we compare non-zero mean in top genes across batches within “Non-progressors” of Africa and G6 studies. Here “top genes” refer to top gene lists from previous DE within control samples comparing batches.
###### Changes in MEAN non-zero gene counts ######
top50 up top50 down 100 least DE
Africa 2072.8 4110.2 446.7
G6 6834.0 3530.7 609.6
###### Changes in MEDIAN non-zero gene counts ######
top50 up top50 down 100 least DE
Africa 473 2413 30
G6 1600 2054 34
Conclusions:
- Mean batch effect fold change (non-zero portion) comparing average counts in top genes ranges from 1.16-3.3 (mean).
- O counts did not strongly affect mean batch effect in terms of average counts in top genes.
Batch mean with 0 counts removed
Median (of all genes) gene-wise mean after removing zeros:
Africa G6 Brazil1
Non-progressor 118.62 155.7 35.33
Progressor 109.31 173.2 33.94
Scaled by that of Africa:
Africa G6 Brazil1
Non-progressor 1 1.31 0.30
Progressor 1 1.58 0.31
Batch dispersion with 0 counts removed
Dispersion estimates are more likely impacted by 0 counts. We re-estimate the dispersions in each batch, using non-zero portion of each gene. Then we compare the dispersion estimates across batches.
#### Statistics about dispersion estimates (from NON-ZERO portions) from the two batches ####
Africa G6 India Brazil_1 Brazil_2
min disp. 0.0000 0.0000 0.0000 0.0000 0.0000
median disp. 0.1293 0.1739 0.1176 0.5544 0.1708
mean disp. 0.1885 0.2359 0.1601 0.5460 0.2548
max disp. 5.0019 4.1344 3.1316 3.7155 4.8316

Conclusions:
- Mean dispersion of Brazil batch 1 is roughly 3.4 times that of India.
- The absolute value of max gene-wise dispersion are reduced after 0 counts are removed.
- In this report, dispersion are calculated by different methods before and after removing 0 counts. Not directly comparable.
- We show in another analysis (TB_run_nonzero_disps.R) that the difference in dispersion is reduced after removing 0s.
Batch variance with 0 counts removed
Median gene-wise variance after removing zeros:
Africa G6 Brazil1
Non-progressor 4871.43 8110.23 964.11
Progressor 4561.47 11948.42 1571.00
Scaled by that of Africa:
Africa G6 Brazil1
Non-progressor 1 1.66 0.20
Progressor 1 2.62 0.34
Is there a difference in zero portions across batches?
Another question related to batch effect, is whether there is any difference in the percentage of 0 counts in a gene between two batches.

Conclusions:
- There isn’t an obvious difference in zero fractions between batches (aside from Brazil batch 2 which is too small).
Goodness of fit for NB distribution to non-zero portion of genes
It is difficult to evaluate quantitatively the goodness-of-fit of NB distribution on data. Instead, we generate Q-Q plots for 100 randomly selected genes, comparing data with NB distribution using ML estimated parameters. We generate these plots within G6/Africa, for cases and control samples separately. Figures are stored under {output_dir}/qqplots_{Study}/.
More justification for having different dispersion parameter for different batches
Finally, a very important assumption of ComBat-seq model (compared to adding batch covariates in linear model of edgeR and DESeq), is that having a different dispersion parameter for each batch is beneficial for DE performance. As argued by many, if not all, of these papers, accurate estimation of dispersion paramters are important for DE detection. As we have seen above, there is some difference in dispersion distribution across batches. If dispersion estimates within each batch and using the whole study are not consistent with each other, then it is justification that we may need different dipsersion parameter for different batches, and it could be good for DE.
Here we generate scatter plots comparing dispersion estimates within each batch to estimates from whole dataset (including batch as a covariate in whole study).
In Brazil
Gene-wise dispersion estimates

Trended dispersion estimates

Africa VS G6
Gene-wise dispersion estimates

Trended dispersion estimates

Brazil Batch 1 VS India
Gene-wise dispersion estimates

Trended dispersion estimates

Session info
R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] parallel stats4 stats graphics grDevices utils datasets methods base
other attached packages:
[1] MASS_7.3-51 ggdendro_0.1-20 scales_1.0.0 gridExtra_2.3
[5] reshape2_1.4.3 ggplot2_3.0.0 dendextend_1.9.0 edgeR_3.22.5
[9] limma_3.36.5 DESeq2_1.20.0 SummarizedExperiment_1.10.1 DelayedArray_0.6.6
[13] BiocParallel_1.14.2 matrixStats_0.54.0 Biobase_2.40.0 GenomicRanges_1.32.7
[17] GenomeInfoDb_1.16.0 IRanges_2.14.12 S4Vectors_0.18.3 BiocGenerics_0.26.0
loaded via a namespace (and not attached):
[1] bitops_1.0-6 bit64_0.9-7 RColorBrewer_1.1-2 rprojroot_1.3-2 prabclus_2.2-6
[6] tools_3.5.1 backports_1.1.2 R6_2.3.0 rpart_4.1-13 Hmisc_4.1-1
[11] DBI_1.0.0 lazyeval_0.2.1 colorspace_1.3-2 trimcluster_0.1-2.1 nnet_7.3-12
[16] withr_2.1.2 tidyselect_0.2.5 bit_1.1-14 compiler_3.5.1 htmlTable_1.12
[21] labeling_0.3 diptest_0.75-7 checkmate_1.8.5 DEoptimR_1.0-8 mvtnorm_1.0-8
[26] robustbase_0.93-3 genefilter_1.62.0 stringr_1.3.1 digest_0.6.18 foreign_0.8-71
[31] rmarkdown_1.10 XVector_0.20.0 base64enc_0.1-3 pkgconfig_2.0.2 htmltools_0.3.6
[36] htmlwidgets_1.3 rlang_0.3.0 rstudioapi_0.8 RSQLite_2.1.1 bindr_0.1.1
[41] jsonlite_1.5 mclust_5.4.1 acepack_1.4.1 dplyr_0.7.7 RCurl_1.95-4.11
[46] magrittr_1.5 modeltools_0.2-22 GenomeInfoDbData_1.1.0 Formula_1.2-3 Matrix_1.2-14
[51] Rcpp_0.12.19 munsell_0.5.0 viridis_0.5.1 stringi_1.2.4 whisker_0.3-2
[56] yaml_2.2.0 zlibbioc_1.26.0 flexmix_2.3-14 plyr_1.8.4 grid_3.5.1
[61] blob_1.1.1 crayon_1.3.4 lattice_0.20-35 splines_3.5.1 annotate_1.58.0
[66] locfit_1.5-9.1 knitr_1.20 pillar_1.3.0 fpc_2.1-11.1 geneplotter_1.58.0
[71] XML_3.98-1.16 glue_1.3.0 evaluate_0.12 latticeExtra_0.6-28 data.table_1.11.8
[76] gtable_0.2.0 purrr_0.2.5 kernlab_0.9-27 assertthat_0.2.0 xtable_1.8-3
[81] viridisLite_0.3.0 class_7.3-14 survival_2.42-6 tibble_1.4.2 AnnotationDbi_1.42.1
[86] memoise_1.1.0 bindrcpp_0.2.2 cluster_2.0.7-1
References
LS0tCnRpdGxlOiAiRXhwbG9yYXRpb24gb2YgcmVhbCBidWxrIFJOQS1zZXEgZGF0YXNldHMiCnN1YnRpdGxlOiAiVEIgZGF0YXNldHMiCmF1dGhvcjogWXVxaW5nIFpoYW5nCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogdW5pdGVkCiAgICB0b2M6IHllcwpiaWJsaW9ncmFwaHk6IHJlZnMuYmliCi0tLQoKIyMgSW50cm9kdWN0aW9uCgpUaGlzIGlzIGEgY3VyYXRlZCBkYXRhc2V0IGNvbnRhaW5pbmcgdGhlIEFmcmljYSwgQnJhemlsLCBJbmRpYSwgYW5kIHRoZSBHNiBkYXRhc2V0cywgd2hpY2ggYXJlIGFsbCBUQiBkYXRhc2V0cyB3aXRoIGFjdGl2ZSBUQiBwYXRpZW50cywgcGF0aWVudHMgdGhhdCB3aWxsIHByb2dyZXNzIHRvIGFjdGl2ZSBUQiwgYW5kIHBlb3BsZSB3aXRoIFRCIGluZmVjdGlvbiB3aG8gZG9u4oCZdCBwcm9ncmVzcy4gVGhlcmUgaXMgYSBiYXRjaCBlZmZlY3QgZXNwZWNpYWxseSB3aXRoIHRoZSBCcmF6aWwgZGF0YS4gVGhpcyBvYmplY3QgaXMgYSBTdW1tYXJpemVkRXhwZXJpbWVudCB3aXRoIDcgYXNzYXlzLiBUaGUg4oCYY29tYmF04oCZIGFzc2F5IHdhcyBtYWRlIGJ5IHJ1bm5pbmcgdGhlIGxvZ3RwbSB2YWx1ZXMgdGhyb3VnaCBjb21iYXQgd2l0aCDigJhTZXF1ZW5jaW5nQmF0Y2jigJkgYXMgdGhlIGJhdGNoIGFuZCDigJhMYWJlbOKAmSBhcyB0aGUgY292YXJpYXRlLiDigJxMYWJlbOKAnSBpcyB0aGUgY29uZGl0aW9uIE5vbi1wcm9ncmVzc29yLCBQcm9ncmVzc29yLCBhbmQgQWN0aXZlLgoKCiMjIyBPdmVyYWxsIGRlc2lnbgoKVGhlIGNvbWJpbmVkIGRhdGFzZXQgY29udGFpbnMgNCBzdHVkaWVzLCBpbiB3aGljaCBCcmF6aWwgZGF0YXNldCBoYXMgMiBiYXRjaGVzIHdpdGhpbiB0aGUgc3R1ZHk6CgorIEFmcmljYTogMTk3IHNhbXBsZXMsICgxMDQgTm9uLXByb2dyZXNzb3IsIDc3IFByb2dyZXNzb3IsIDE2IEFjdGl2ZSkKKyBCcmF6aWw6IDUxIHNhbXBsZXMsICgyMSBOb24tcHJvZ3Jlc3NvciwgMTYgUHJvZ3Jlc3NvciwgMTQgQWN0aXZlKQogICAgLSBCYXRjaCAxOiAzOSBzYW1wbGVzLCAoOSBOb24tcHJvZ3Jlc3NvciwgMTYgUHJvZ3Jlc3NvciwgMTQgQWN0aXZlKQogICAgLSBCYXRjaCAyOiAxMiBzYW1wbGVzLCAoMTIgTm9uLXByb2dyZXNzb3IsIDAgUHJvZ3Jlc3NvciwgMCBBY3RpdmUpCisgRzY6IDM5OSBzYW1wbGVzLCAoMzA0IE5vbi1wcm9ncmVzc29yLCA5NSBQcm9ncmVzc29yLCAwIEFjdGl2ZSkKKyBJbmRpYTogNDQgc2FtcGxlcywgKDE5IE5vbi1wcm9ncmVzc29yLCAwIFByb2dyZXNzb3IsIDI1IEFjdGl2ZSkKCioqTm90ZSoqOiBHZW5kZXIgaXMgYW4gaW1wb3J0YW50IGZhY3RvciBpbiB0aGlzIHN0dWR5LgoKCiMjIyBMb2FkIGRhdGEgJiBzdW1tYXJpemUgYmFzaWMgaW5mbwoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQpybShsaXN0PWxzKCkpCm91dHB1dF9kaXIgPC0gIn4vR29vZ2xlIERyaXZlL0NvbUJhdF9zZXEvcmVhbF9kYXRhX2V4YW1wbGUvUk5Bc2VxL1RCIgpzYXBwbHkoYygiU3VtbWFyaXplZEV4cGVyaW1lbnQiLCAiREVTZXEyIiwgImVkZ2VSIiwgImRlbmRleHRlbmQiLCAiZ2dwbG90MiIsICJyZXNoYXBlMiIsIAogICAgICAgICAiZ3JpZEV4dHJhIiwgInNjYWxlcyIsICJnZ2RlbmRybyIsICJNQVNTIiksIHJlcXVpcmUsIGNoYXJhY3Rlci5vbmx5PVRSVUUpCgojIyMjICBMb2FkIGRhdGEKcmRzX29iaiA8LSByZWFkUkRTKGZpbGUucGF0aChvdXRwdXRfZGlyLCAiY29tYmluZWQucmRzIikpCmN0cyA8LSBhc3NheXMocmRzX29iaikkY291bnRzCiMgYmF0Y2ggaW5kaWNhdG9yCmJhdGNoIDwtIGNvbERhdGEocmRzX29iaikkU2VxdWVuY2luZ0JhdGNoCiMgY29uZGl0aW9uIGluZGljYXRvcgpncm91cCA8LSBjb2xEYXRhKHJkc19vYmopJExhYmVsCmBgYAoKQWZ0ZXIgbG9hZGluZyB0aGUgZGF0YSwgd2UgY2FsY3VsYXRlIGEgZmV3IGJhc2ljIHN0YXRpc3RpY3Mgb2YgdGhlIGRhdGFzZXQuCgpgYGB7ciwgZWNobz1GQUxTRX0KY2F0KCIjIyMjIyMgIFNhbXBsZXMgICMjIyMjIyNcbiIpCmNhdCgiLSBUb3RhbCBudW1iZXIgb2Ygc2FtcGxlczpcbiIpCnByaW50KG5jb2woY3RzKSkKCmNhdCgiXG4tIE51bWJlciBvZiBzYW1wbGVzIGluIGNvbmRpdGlvbiBncm91cHM6XG4iKQpwcmludCh0YWJsZShncm91cCkpCgpjYXQoIlxuLSBOdW1iZXIgb2Ygc2FtcGxlcyBpbiBiYXRjaGVzOlxuIikKcHJpbnQodGFibGUoYmF0Y2gpKQpjYXQoIlxuSW4gZWFjaCBiYXRjaCBzZXBhcmF0ZWx5OlxuIikKbl9iYXRjaGVzIDwtIGxhcHBseShsZXZlbHMoYmF0Y2gpLCBmdW5jdGlvbihjdXJyX2JhdGNoKXsKICB0YWJsZShncm91cFtiYXRjaD09Y3Vycl9iYXRjaF0pCn0pCm5fYmF0Y2hlcyA8LSBkby5jYWxsKHJiaW5kLCBuX2JhdGNoZXMpCnJvd25hbWVzKG5fYmF0Y2hlcykgPC0gbGV2ZWxzKGJhdGNoKQpwcmludChuX2JhdGNoZXMpCgoKY2F0KCJcblxuIyMjIyMjICBHZW5lcyAgIyMjIyMjI1xuIikKY2F0KCItIFRvdGFsIG51bWJlciBvZiBnZW5lczpcbiIpCnByaW50KG5yb3coY3RzKSkKCmNhdCgiXG4tIE51bWJlciBvZiBnZW5lcyB3aXRoIDAgY291bnRzOlxuIikKZ2VuZV9yb3dfd2l0aF96ZXJvcyA8LSBhcHBseShjdHMsIDEsIGZ1bmN0aW9uKHgpe2FueSh4PT0wKX0pCmNhdChjKHN1bShnZW5lX3Jvd193aXRoX3plcm9zKSwgcGVyY2VudChzdW0oZ2VuZV9yb3dfd2l0aF96ZXJvcykvbnJvdyhjdHMpKSkpCgpjYXQoIlxuXG4tIE51bWJlciBvZiBnZW5lcyB3aXRoIG1heGltdW0gMTAgY291bnRzOlxuIikKZ2VuZV9yb3dfbG93IDwtIGFwcGx5KGN0cywgMSwgZnVuY3Rpb24oeCl7YWxsKHg8PTEwKX0pCmNhdChjKHN1bShnZW5lX3Jvd19sb3cpLCBwZXJjZW50KHN1bShnZW5lX3Jvd19sb3cpL25yb3coY3RzKSkpKQoKY2F0KCJcblxuLSBOdW1iZXIgb2YgZ2VuZXMgd2l0aCBPTkxZIDBzOlxuIikKZ2VuZV9hbGxfemVyb3MgPC0gYXBwbHkoY3RzLCAxLCBmdW5jdGlvbih4KXthbGwoeD09MCl9KQpjYXQoYyhzdW0oZ2VuZV9hbGxfemVyb3MpLCBwZXJjZW50KHN1bShnZW5lX2FsbF96ZXJvcykvbnJvdyhjdHMpKSkpCgoKY2F0KCJcblxuXG4jIyMjIyMgIENvdW50cyAgIyMjIyMjI1xuIikKY2F0KCItIFJhbmdlIG9mIGNvdW50IGluIHdob2xlIGRhdGFzZXQ6XG4iKQpwcmludChyb3VuZChyYW5nZShjdHMpLCAzKSkKCmNhdCgiXG4tIEF2ZXJhZ2UgY291bnQgaW4gd2hvbGUgZGF0YXNldDpcbiIpCnByaW50KHBhc3RlKCJNZWFuOiIsIHJvdW5kKG1lYW4oY3RzKSwgMykpKQpwcmludChwYXN0ZSgiTWVkaWFuOiIsIHJvdW5kKG1lZGlhbihjdHMpLCAzKSkpCgpybShnZW5lX3Jvd193aXRoX3plcm9zLCBnZW5lX3Jvd19sb3csIGdlbmVfYWxsX3plcm9zKQpgYGAKClRoZXJlIGFyZSBubyBnZW5lcyB3aXRoIG9ubHkgemVybyB2YWx1ZXMgYWNyb3NzIGFsbCBzYW1wbGVzIChwcm9iYWJseSBiZWNhdXNlIG9mIGNsZWFuaW5nIGluIHRoZSBjdXJhdGlvbiBzdGFnZSkuIFRoZSBmaWd1cmUgYmVsb3cgc2hvd3MgZGlzdHJpYnV0aW9uIG9mIHBlcmNlbnRhZ2VzIG9mIHplcm8gY291bnRzIGZvciB0aGUgcmVtYWluaW5nIGdlbmVzIChlYWNoIGRhdGEgcG9pbnQgcmVwcmVzZW50cyBhIGdlbmUsIGkuZS4sIGhvdyBtYW55IHplcm9zIGFyZSB0aGVyZSBpbiBlYWNoIGdlbmUpLgoKYGBge3IsIGVjaG89RkFMU0V9Cm5femVyb3NfaW5fZ2VuZXMgPC0gYXBwbHkoY3RzLCAxLCBmdW5jdGlvbih4KXtsZW5ndGgod2hpY2goeD09MCkpfSkKcGVyY2VudF96ZXJvc19pbl9nZW5lcyA8LSBuX3plcm9zX2luX2dlbmVzIC8gbmNvbChjdHMpCnBlcmNlbnRfemVyb3NfZGYgPC0gZGF0YS5mcmFtZShnZW5lcz1yb3duYW1lcyhjdHMpLCB2YWx1ZT1wZXJjZW50X3plcm9zX2luX2dlbmVzKQoKYmlubmVkX2N0cyA8LSBoaXN0KHBlcmNlbnRfemVyb3NfaW5fZ2VuZXMsIGJyZWFrcz0xMCwgcGxvdD1GQUxTRSkkY291bnRzIApiaW5uZWRfcHJvcG9ydGlvbnMgPC0gYmlubmVkX2N0cyAvIHN1bShiaW5uZWRfY3RzKQpuYW1lcyhiaW5uZWRfcHJvcG9ydGlvbnMpIDwtIHBhc3RlMCgiPCIsIHBlcmNlbnQoc2VxKGZyb209MC4xLCB0bz0xLCBieT0wLjEpKSkgIApjYXQoIiMjIyMjIyAgUHJvcG9ydGlvbiBvZiBnZW5lcyB3aXRoIFglIHplcm9zIGFjcm9zcyBzYW1wbGVzICAjIyMjIyMjXG4iKQpwcmludChyb3VuZChiaW5uZWRfcHJvcG9ydGlvbnMsMykpCgpnZ3Bsb3QocGVyY2VudF96ZXJvc19kZiwgYWVzKDAsIHZhbHVlKSkgKyAKICAgICAgZ2VvbV92aW9saW4oKSArCiAgICAgIGdlb21fYm94cGxvdChhZXMoMC43LCB2YWx1ZSksIHdpZHRoPTAuMTUpICsKICAgICAgY29vcmRfZmxpcCgpICsKICAgICAgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIGxhYmVsPXBlcmNlbnQobWVkaWFuKHBlcmNlbnRfemVyb3NfZGYkdmFsdWUpKSwgeD0wLjg1LCB5PW1lZGlhbihwZXJjZW50X3plcm9zX2RmJHZhbHVlKSkgKwogICAgICBsYWJzKHk9IiUgWmVyb3MiLCB0aXRsZT0iUHJvcG9ydGlvbiBvZiB6ZXJvcyBhY3Jvc3Mgc2FtcGxlcyBmb3IgdGhlIHJlbWFpbmluZyBnZW5lcyIpICsKICAgICAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkjLCBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3IsIGVjaG89RkFMU0V9CnJtKG5femVyb3NfaW5fZ2VuZXMsIHBlcmNlbnRfemVyb3NfaW5fZ2VuZXMsIHBlcmNlbnRfemVyb3NfZGYpCmBgYAoKCgojIyBFeGlzdGVuY2Ugb2YgYmF0Y2ggZWZmZWN0IHsudGFic2V0fQoKSW4gdGhpcyBtZXJnZWQgZGF0YXNldCwgdGhlcmUgYXJlIGJvdGggInN0dWR5IGVmZmVjdHMiIGFjcm9zcyB0aGUgNCBzdHVkaWVzICh0YXJnZXRpbmcgZGlmZmVyZW50IHBvcHVsYXRpb25zKSwgYW5kIGJhdGNoIGVmZmVjdCB3aXRoaW4gdGhlIHNhbWUgc3R1ZHkgKEJyYXppbCBkYXRhc2V0KS4KCiMjIyBQQ0EKCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTV9CnBjYV9vYmogPC0gcGxvdFBDQShERVNlcVRyYW5zZm9ybShyZHNfb2JqKSwgaW50Z3JvdXA9YygiU2VxdWVuY2luZ0JhdGNoIiwgIkxhYmVsIiwgIlNleCIsICJEYXRhc2V0IikpIApwX2JhdGNoIDwtIGdncGxvdChwY2Ffb2JqJGRhdGEsIGFlcyh4PVBDMSwgeT1QQzIsIGNvbG9yPVNlcXVlbmNpbmdCYXRjaCkpICsKICBnZW9tX3BvaW50KCkgKyAKICBsYWJzKHg9c3ByaW50ZigiUEMxOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29iaiRwbG90X2VudiRwZXJjZW50VmFyWzFdKSksCiAgICAgICB5PXNwcmludGYoIlBDMjogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmokcGxvdF9lbnYkcGVyY2VudFZhclsyXSkpLAogICAgICAgdGl0bGU9IlBDQTogc2FtcGxlcyBjb2xvcmVkIGJ5IEJhdGNoIikKcF9jb25kIDwtIGdncGxvdChwY2Ffb2JqJGRhdGEsIGFlcyh4PVBDMSwgeT1QQzIsIGNvbG9yPUxhYmVsKSkgKwogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeD1zcHJpbnRmKCJQQzE6ICVzIFZhcmlhbmNlIiwgcGVyY2VudChwY2Ffb2JqJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29iaiRwbG90X2VudiRwZXJjZW50VmFyWzJdKSksCiAgICAgICB0aXRsZT0iUENBOiBzYW1wbGVzIGNvbG9yZWQgYnkgQ29uZGl0aW9uIikKcF9zdHVkaWVzIDwtIGdncGxvdChwY2Ffb2JqJGRhdGEsIGFlcyh4PVBDMSwgeT1QQzIsIGNvbG9yPURhdGFzZXQpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4PXNwcmludGYoIlBDMTogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmokcGxvdF9lbnYkcGVyY2VudFZhclsxXSkpLAogICAgICAgeT1zcHJpbnRmKCJQQzI6ICVzIFZhcmlhbmNlIiwgcGVyY2VudChwY2Ffb2JqJHBsb3RfZW52JHBlcmNlbnRWYXJbMl0pKSwKICAgICAgIHRpdGxlPSJQQ0E6IHNhbXBsZXMgY29sb3JlZCBieSBTdHVkaWVzIikKcF9zZXggPC0gZ2dwbG90KHBjYV9vYmokZGF0YSwgYWVzKHg9UEMxLCB5PVBDMiwgY29sb3I9U2V4KSkgKwogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeD1zcHJpbnRmKCJQQzE6ICVzIFZhcmlhbmNlIiwgcGVyY2VudChwY2Ffb2JqJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29iaiRwbG90X2VudiRwZXJjZW50VmFyWzJdKSksCiAgICAgICB0aXRsZT0iUENBOiBzYW1wbGVzIGNvbG9yZWQgYnkgU2V4IikKZ3JpZC5hcnJhbmdlKHBfYmF0Y2gsIHBfY29uZCwgcF9zdHVkaWVzLCBwX3NleCwgbnJvdz0yLCBuY29sPTIpCmBgYAoKCiMjIyBQQ0EgKEJyYXppbCBvbmx5KQoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MiwgZmlnLndpZHRoPTV9CnJkc19icmF6aWwgPC0gcmRzX29ialssIHJkc19vYmokRGF0YXNldD09IkJyYXppbCJdCgpwY2Ffb2JqX2JyYXppbCA8LSBwbG90UENBKERFU2VxVHJhbnNmb3JtKHJkc19icmF6aWwpLCBpbnRncm91cD1jKCJTZXF1ZW5jaW5nQmF0Y2giLCAiTGFiZWwiKSkgCnBiX2JhdGNoIDwtIGdncGxvdChwY2Ffb2JqX2JyYXppbCRkYXRhLCBhZXMoeD1QQzEsIHk9UEMyLCBjb2xvcj1TZXF1ZW5jaW5nQmF0Y2gpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4PXNwcmludGYoIlBDMTogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmpfYnJhemlsJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29ial9icmF6aWwkcGxvdF9lbnYkcGVyY2VudFZhclsyXSkpLAogICAgICAgdGl0bGU9IlBDQTogc2FtcGxlcyBjb2xvcmVkIGJ5IEJhdGNoIikKcGJfY29uZCA8LSBnZ3Bsb3QocGNhX29ial9icmF6aWwkZGF0YSwgYWVzKHg9UEMxLCB5PVBDMiwgY29sb3I9TGFiZWwpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4PXNwcmludGYoIlBDMTogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmpfYnJhemlsJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29ial9icmF6aWwkcGxvdF9lbnYkcGVyY2VudFZhclsyXSkpLAogICAgICAgdGl0bGU9IlBDQTogc2FtcGxlcyBjb2xvcmVkIGJ5IENvbmRpdGlvbiIpCmdyaWQuYXJyYW5nZShwYl9iYXRjaCwgcGJfY29uZCwgbmNvbD0yKQpgYGAKCgojIyMgRGVuZHJvZ3JhbXMgKEJyYXppbCBvbmx5KQoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9Mi44LCBmaWcud2lkdGg9NS41fQpjb3VudHNfbm9ybSA8LSBzY2FsZSh0KGFzc2F5KHJkc19icmF6aWwsImNvdW50cyIpKSwgY2VudGVyPVRSVUUsIHNjYWxlPVRSVUUpCmhjIDwtIGhjbHVzdChkaXN0KGNvdW50c19ub3JtKSkKZGVuZCA8LSBhcy5kZW5kcm9ncmFtKGhjKQpkZGF0YSA8LSBkZW5kcm9fZGF0YShkZW5kLCB0eXBlPSJyZWN0YW5nbGUiKQoKbWV0YV9pbmZvIDwtIGRhdGEuZnJhbWUoY29sRGF0YShyZHNfYnJhemlsKVssIGMoIlNlcXVlbmNpbmdCYXRjaCIsICJMYWJlbCIpXSwgc2FtcGxlPWNvbG5hbWVzKHJkc19icmF6aWwpKQp0bXAgPC0gbWVyZ2UoeD1kZGF0YSRsYWJlbHMsIHk9bWV0YV9pbmZvLCBieS54PSJsYWJlbCIsIGJ5Lnk9InNhbXBsZSIpCgpwZF9iYXRjaCA8LSBnZ3Bsb3Qoc2VnbWVudChkZGF0YSkpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4PXgsIHk9eSwgeGVuZD14ZW5kLCB5ZW5kPXllbmQpKSArIAogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJyNFNjlGMDAnLCAnIzU2QjRFOScpKSArCiAgZ2VvbV90ZXh0KGRhdGE9dG1wLCBhZXMobGFiZWw9dG1wJGxhYmVsLCB4PXgsIHk9LTEwLCBjb2xvdXI9U2VxdWVuY2luZ0JhdGNoKSkgKwogIGxhYnMoeD0iIiwgeT0iIiwgdGl0bGU9IkNsdXN0ZXJpbmc6IHNhbXBsZXMgY29sb3JlZCBieSBCYXRjaCIpCnBkX2NvbmQgPC0gZ2dwbG90KHNlZ21lbnQoZGRhdGEpKSArIAogIGdlb21fc2VnbWVudChhZXMoeD14LCB5PXksIHhlbmQ9eGVuZCwgeWVuZD15ZW5kKSkgKyAKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X3JldmVyc2UoKSArCiAgZ2VvbV90ZXh0KGRhdGE9dG1wLCBhZXMobGFiZWw9dG1wJGxhYmVsLCB4PXgsIHk9LTEwLCBjb2xvdXI9TGFiZWwpKSArCiAgbGFicyh4PSIiLCB5PSIiLCB0aXRsZT0iQ2x1c3RlcmluZzogc2FtcGxlcyBjb2xvcmVkIGJ5IENvbmRpdGlvbiIpCmdyaWQuYXJyYW5nZShwZF9iYXRjaCwgcGRfY29uZCwgbmNvbD0yKQoKcm0oY291bnRzX25vcm0sIGRkYXRhLCBkZW5kLCBoYywgcF9iYXRjaCwgcF9jb25kLCBwX3N0dWRpZXMsIHBfc2V4LCBwY2Ffb2JqLCBwZF9iYXRjaCwgcGRfY29uZCwgdG1wLAogICBwY2Ffb2JqX2JyYXppbCwgcGJfYmF0Y2gsIHBiX2NvbmQpCmBgYAoKCgojIyBMaWJyYXJ5IHNpemUKCk5leHQsIHdlIHRha2UgYSBsb29rIGF0IHRoZSBvYnNlcnZlZCBsaWJyYXJ5IHNpemVzIG9mIHNhbXBsZXMsIGFuZCB0byBzZWUgaWYgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluIGxpYnJhcnkgc2l6ZSBhY3Jvc3MgYmF0Y2hlcy4KCmBgYHtyLCBlY2hvPUZBTFNFfQojIyMgIERpc3RyaWJ1dGlvbiBvZiBsaWJyYXJ5IHNpemUKbGliX3NpemVzIDwtIGNvbFN1bXMoY3RzKQpjYXQoIlJhbmdlIG9mIG9ic2VydmVkIGxpYnJhcnkgc2l6ZXMgYWNyb3NzIHNhbXBsZXM6XG4iKQpwcmludChzY2llbnRpZmljKHJhbmdlKGxpYl9zaXplcykpKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTIsIGZpZy53aWR0aD00LjV9CmxpYl9zaXplc19kZiA8LSBkYXRhLmZyYW1lKGxpYl9zaXplcz1saWJfc2l6ZXMsIGJhdGNoPWJhdGNoKQoKIyBvdmVyYWxsIHNhbXBsZSBsaWJyYXJ5IHNpemVzCnBsaWIxIDwtIGdncGxvdChsaWJfc2l6ZXNfZGYsIGFlcyh4PWxpYl9zaXplcykpICsgCiAgZ2VvbV9oaXN0b2dyYW0oYmlucz1yb3VuZChuY29sKHJkc19vYmopLzUpKSArCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1tZWFuKGxpYl9zaXplcykpLCBjb2xvcj0icmVkIiwgbGluZXR5cGU9ImRhc2hlZCIsIHNpemU9MSkgKwogIGFubm90YXRlKGdlb209InRleHQiLCB4PW1lYW4obGliX3NpemVzKSwgeT1tYXgoaGlzdChsaWJfc2l6ZXMsIHBsb3Q9RkFMU0UpJGNvdW50cykrMSwgCiAgICAgICAgICAgbGFiZWw9c2NpZW50aWZpYyhtZWFuKGxpYl9zaXplcykpLCBjb2xvcj0icmVkIikgKwogIGxhYnMoeD0iTGlicmFyeSBzaXplcyBpbiBzYW1wbGVzIiwgeT0iTnVtYmVyIG9mIHNhbXBsZXMiLCAKICAgICAgIHRpdGxlPSJEaXN0cmlidXRpb24gb2Ygb2JzZXJ2ZWQgbGlicmFyeSBzaXplcyIpIAoKIyBib3hwbG90IGNvbXBhcmluZyBkaXN0cmlidXRpb24gb2YgbGlicmFyeSBzaXplIGFjcm9zcyBiYXRjaGVzCnBsaWIyIDwtIGdncGxvdChsaWJfc2l6ZXNfZGYsIGFlcyh4PWJhdGNoLCB5PWxpYl9zaXplcywgZmlsbD1iYXRjaCkpICsgCiAgZ2VvbV9ib3hwbG90KCkgKwogIGxhYnMoeD0iIiwgeT0iTGlicmFyeSBzaXplcyIsIHRpdGxlPSJDb21wYXJlIGxpYnJhcnkgc2l6ZXMgYWNyb3NzIGJhdGNoIikgCgpncmlkLmFycmFuZ2UocGxpYjEsIHBsaWIyLCBuY29sPTIpCgpybShwbGliMSwgcGxpYjIpCmBgYAoKCgojIyBHZW5lIGV4cHJlc3Npb24gZGlzdHJpYnV0aW9uCgpPdXIgbmV4dCBzdGVwIGlzIHRvIGludGVycm9nYXRlIHRoZSBnZW5lIGV4cHJlc3Npb24gZGlzdHJpYnV0aW9ucy4gCgo8IS0tCldlIGZpcnN0IHNpbXBseSBwbG90IHRoZSBjb3VudHMsIENQTSwgYW5kIGxvZzJDUE0gb2YgMjAgcmFuZG9tbHkgY2hvc2VuIGdlbmVzIGluIHRoZSBkYXRhc2V0LiBUaGVzZSBmaWd1cmVzIGFyZSBzdG9yZWQgdW5kZXIgZGlyZWN0b3J5IHNwZWNpZmllZCBieSB7b3V0cHV0X2Rpcn0vcmFuZEdwbG90cy8uICAKLS0+IAoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBldmFsPUZBTFNFfQppZighZGlyLmV4aXN0cyhmaWxlLnBhdGgob3V0cHV0X2RpciwgInJhbmRHcGxvdHMiKSkpe2Rpci5jcmVhdGUoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJyYW5kR3Bsb3RzIikpfQpzZXQuc2VlZCgxMjMpCk5fc2VsIDwtIDIwCmNob3Nlbl9pZCA8LSBzYW1wbGUoMTpucm93KHJkc19vYmopLCBOX3NlbCwgcmVwbGFjZT1GQUxTRSkKCmN0c19zdWJzZXQgPC0gY3RzW2Nob3Nlbl9pZCwgXQpjcG1fc3Vic2V0IDwtIGNwbShjdHMsIGxvZz1GQUxTRSlbY2hvc2VuX2lkLCBdCmxvZ0NQTV9zdWJzZXQgPC0gY3BtKGN0cywgbG9nPVRSVUUpW2Nob3Nlbl9pZCwgXQpkYXRhX2xzdCA8LSBsaXN0KENvdW50cz1jdHNfc3Vic2V0LCBDUE09Y3BtX3N1YnNldCwgbG9nMkNQTT1sb2dDUE1fc3Vic2V0KQoKdm9pZCA8LSBtYXBwbHkoZnVuY3Rpb24oZGF0LCBkYXRfbmFtZSwgbWV0YV9pbmZvKXsKICBmb3IoaSBpbiAxOm5yb3coZGF0KSl7CiAgICAjIHByZXBhcmUgZGF0YSBmcmFtZQogICAgY3Vycl9kZiA8LSBkYXRhLmZyYW1lKHNhbXBsZXM9Y29sbmFtZXMoZGF0KSwgdmFsdWU9ZGF0W2ksIF0pCiAgICBjdXJyX2RmIDwtIG1lcmdlKHg9Y3Vycl9kZiwgeT1tZXRhX2luZm8sIGJ5Lng9InNhbXBsZXMiLCBieS55PSJzYW1wbGUiKQogICAgCiAgICAjIHNjYXR0ZXIgcGxvdCBmb3IgaS10aCBnZW5lCiAgICBwX3NjYXR0ZXIgPC0gZ2dwbG90KGN1cnJfZGYsIGFlcyh4PXNhbXBsZXMsIHk9dmFsdWUsIGNvbG9yPWJhdGNoLCBzaGFwZT1jb25kKSkgKwogICAgICBnZW9tX3BvaW50KCkgKwogICAgICBsYWJzKHg9IlNhbXBsZXMiLCB5PWRhdF9uYW1lLCB0aXRsZT1yb3duYW1lcyhkYXQpW2ldKSArCiAgICAgIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyB2aW9saW4gcGxvdCBmb3IgaS10aCBnZW5lCiAgICBwX3Zpb2xpbiA8LSBnZ3Bsb3QoY3Vycl9kZiwgYWVzKDAsIHZhbHVlKSkgKyAKICAgICAgZ2VvbV92aW9saW4oKSArCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0wLjIpICsKICAgICAgY29vcmRfZmxpcCgpICsKICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1hcy5pbnRlZ2VyKG1lZGlhbihjdXJyX2RmJHZhbHVlKSksIHg9MC4xMiwgeT1tZWRpYW4oY3Vycl9kZiR2YWx1ZSkpKSArCiAgICAgIGxhYnMoeT1kYXRfbmFtZSwgdGl0bGU9c3ByaW50ZigiQWxsIHNhbXBsZXMsICVzIiwgcm93bmFtZXMoZGF0KVtpXSkpICsKICAgICAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyB2aW9saW4gcGxvdCBncm91cCBieSBiYXRjaAogICAgbWVkaWFuc19iYXRjaCA8LSBhZ2dyZWdhdGUodmFsdWUgfiBiYXRjaCwgZGF0YT1jdXJyX2RmLCBGVU49bWVkaWFuKQogICAgcF92aW9saW5fYmF0Y2ggPC0gZ2dwbG90KGN1cnJfZGYsIGFlcyh4PWJhdGNoLCB5PXZhbHVlLCBjb2xvcj1iYXRjaCkpICsgCiAgICAgIGdlb21fdmlvbGluKCkgKwogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9MC4yKSArCiAgICAgIGNvb3JkX2ZsaXAoKSArCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygnI0U2OUYwMCcsICcjNTZCNEU5JykpICsKICAgICAgZ2VvbV90ZXh0KGRhdGE9bWVkaWFuc19iYXRjaCwgCiAgICAgICAgICAgICAgICBhZXMobGFiZWw9cm91bmQobWVkaWFuc19iYXRjaCR2YWx1ZSwyKSwgeD1hcy5udW1lcmljKGFzLmNoYXJhY3RlcihtZWRpYW5zX2JhdGNoJGJhdGNoKSkrMC4xMiwKICAgICAgICAgICAgICAgICAgICB5PWFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1lZGlhbnNfYmF0Y2gkdmFsdWUpKSkpICsKICAgICAgbGFicyh5PWRhdF9uYW1lLCB0aXRsZT1zcHJpbnRmKCJJbiBiYXRjaGVzLCAlcyIsIHJvd25hbWVzKGRhdClbaV0pKSArCiAgICAgIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpCiAgICAKICAgICMgdmlvbGluIHBsb3QgZ3JvdXAgYnkgY29uZGl0aW9uCiAgICBtZWRpYW5zX2NvbmQgPC0gYWdncmVnYXRlKHZhbHVlIH4gY29uZCwgZGF0YT1jdXJyX2RmLCBGVU49bWVkaWFuKQogICAgcF92aW9saW5fY29uZCA8LSBnZ3Bsb3QoY3Vycl9kZiwgYWVzKHg9Y29uZCwgeT12YWx1ZSwgY29sb3I9Y29uZCkpICsgCiAgICAgIGdlb21fdmlvbGluKCkgKwogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9MC4yKSArCiAgICAgIGNvb3JkX2ZsaXAoKSArCiAgICAgIGdlb21fdGV4dChkYXRhPW1lZGlhbnNfY29uZCwKICAgICAgICAgICAgICAgIGFlcyhsYWJlbD1yb3VuZChtZWRpYW5zX2NvbmQkdmFsdWUsMiksIHg9YXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIobWVkaWFuc19jb25kJGNvbmQpKSsxLjEyLCAKICAgICAgICAgICAgICAgICAgICB5PWFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1lZGlhbnNfY29uZCR2YWx1ZSkpKSkgKwogICAgICBsYWJzKHk9ZGF0X25hbWUsIHRpdGxlPXNwcmludGYoIkluIGNvbmRpdGlvbiBncm91cHMsICVzIiwgcm93bmFtZXMoZGF0KVtpXSkpICsKICAgICAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyBvdXRwdXQgcGxvdAogICAgcG5nKHNwcmludGYoIiVzLyVzX2dlbmUlcy5wbmciLCBmaWxlLnBhdGgob3V0cHV0X2RpciwgInJhbmRHcGxvdHMiKSwgZGF0X25hbWUsIGkpLAogICAgICAgIHdpZHRoPTEwLCBoZWlnaHQ9OCwgdW5pdHM9ImluIiwgcmVzPTMwMCkKICAgIGdyaWQuYXJyYW5nZShwX3NjYXR0ZXIsIHBfdmlvbGluLCBwX3Zpb2xpbl9iYXRjaCwgcF92aW9saW5fY29uZCwgbnJvdz0yLCBuY29sPTIpCiAgICBkZXYub2ZmKCkKICB9Cn0sIGRhdD1kYXRhX2xzdCwgZGF0X25hbWU9bmFtZXMoZGF0YV9sc3QpLCBtZXRhX2luZm89bGlzdChtZXRhX2luZm8sbWV0YV9pbmZvLG1ldGFfaW5mbykpCgpybShjdHNfc3Vic2V0LCBjcG1fc3Vic2V0LCBsb2dDUE1fc3Vic2V0LCBsaWJfc2l6ZXMsIGxpYl9zaXplc19kZiwgY2hvc2VuX2lkLCBkYXRhX2xzdCwgdm9pZCwgTl9zZWwpCmBgYAoKCiMjIyBGb2xkIGNoYW5nZXMgaW4gbWVhbiB7LnRhYnNldH0KCldlIHVzZSBlZGdlUiB0byBwZXJmb3JtIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2lzLCBhbmQgY2FsY3VsYXRlIChsb2ctKSBmb2xkIGNoYW5nZXMgb2YgYWxsIGdlbmVzIGJldHdlZW4gY29uZGl0aW9uIGdyb3VwcyBhbmQgYmF0Y2hlcy4KCiMjIyMgQ2hhbmdlIFdSVCBjb25kaXRpb24KClRvIHJ1bGUgb3V0IHRoZSBpbXBhY3Qgb2YgYmF0Y2ggZWZmZWN0LCB3ZSBsaW1pdCBvdXIgREUgYW5hbHlzaXMgd2l0aCByZWdhcmQgdG8gYmlvbG9naWNhbCBjb25kaXRpb24gaW4gb25lIG9mIHRoZSBiYXRjaGVzLiBIZXJlIHdlIHNwZWNpZnkgdGhlIGJhdGNoIHRvIGJlICoqRzYqKiBkdWUgdG8gYSBsYXJnZXIgYmF0Y2ggc2l6ZSwgYW5kIGV2YWx1YXRlIERFICoqYmV0d2VlbiBwcm9ncmVzc29ycyBhbmQgbm9uLXByb2dyZXNzb3JzKiouCgpgYGB7ciwgcmVzdWx0cz0iaGlkZSJ9CiMjIyMgIERpZmZlcmVudGlhbCBnZW5lcyByZWxhdGl2ZSB0byBiaW9sb2dpY2FsIGNvbmRpdGlvbiAKIyMjIyAgKHdpdGhpbiBiYXRjaCAxIC8gYmF0Y2ggc3BlY2lmaWVkIGJ5ICd0ZXN0X2JhdGNoJykKdGVzdF9iYXRjaCA8LSAiRzYiCmNvdW50c19iYXRjaCA8LSBhc3NheShyZHNfb2JqLCJjb3VudHMiKVssIGJhdGNoPT10ZXN0X2JhdGNoXQpjb25kX2JhdGNoIDwtIGFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PXRlc3RfYmF0Y2hdKSkKCnkgPC0gREdFTGlzdChjb3VudHM9Y291bnRzX2JhdGNoLCBncm91cD1hcy5mYWN0b3IoY29uZF9iYXRjaCkpCnkgPC0gY2FsY05vcm1GYWN0b3JzKHksIG1ldGhvZD0iVE1NIikKZGVzaWduIDwtIG1vZGVsLm1hdHJpeCh+YXMuZmFjdG9yKGNvbmRfYmF0Y2gpKQp5IDwtIGVzdGltYXRlRGlzcCh5LCBkZXNpZ24pCmZpdCA8LSBnbG1RTEZpdCh5LCBkZXNpZ24pCnFsZiA8LSBnbG1RTEZUZXN0KGZpdCwgY29lZj0yKQpkZV9yZXMgPC0gdG9wVGFncyhxbGYsIG49bnJvdyhyZHNfb2JqKSkKIAp1cF9nZW5lcyA8LSByb3duYW1lcyhkZV9yZXMpW2RlX3JlcyR0YWJsZSRsb2dGQyA+PSAwXSAgIyBhbGwgdXAtcmVndWxhdGVkIGdlbmVzIChkZXNjZW5kaW5nIG9yZGVyIGluIHRlcm1zIG9mIHAgdmFsdWUpCmhlYWRfdXBfZ2VuZXMgPC0gaGVhZCh1cF9nZW5lcywgbj01MCkgICMgdG9wLTUwIHNpZ25pZmljYW50IHVwLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX3VwX2dlbmVzIDwtIHRhaWwodXBfZ2VuZXMsIG49NTApICAjIDUwIGxlYXN0IHNpZ25pZmljYW50IHVwLXJlZ3VsYXRlZCBnZW5lcwoKY29uZF91cF9pbmRzIDwtIHVwX2dlbmVzCgpkb3duX2dlbmVzIDwtIHJvd25hbWVzKGRlX3JlcylbZGVfcmVzJHRhYmxlJGxvZ0ZDIDwgMF0gICMgYWxsIGRvd24tcmVndWxhdGVkIGdlbmVzCmhlYWRfZG93bl9nZW5lcyA8LSBoZWFkKGRvd25fZ2VuZXMsIG49NTApICAjIHRvcC01MCBzaWduaWZpY2FudCBkb3duLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX2Rvd25fZ2VuZXMgPC0gdGFpbChkb3duX2dlbmVzLCBuPTUwKSAgIyA1MCBsZWFzdCBzaWduaWZpY2FudCBkb3duLXJlZ3VsYXRlZCBnZW5lcwoKY29uZF9kb3duX2luZHMgPC0gZG93bl9nZW5lcwpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIGNoYW5nZXMgaW4gdGVybXMgb2YgbWVhbgpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiB0ZXJtcyBvZiBhdmVyYWdlIGdlbmUgY291bnRzICAjIyMjIyNcbiIpCm1lYW5fY3RzX21hdCA8LSBtYXRyaXgoTkEsIG5yb3c9MiwgbmNvbD0zLCAKICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIk5vbi1wcm9ncmVzc29yIiwgIlByb2dyZXNzb3IiKSwgYygidG9wNTAgdXAiLCAidG9wNTAgZG93biIsICIxMDAgbGVhc3QgREUiKSkpCm1lYW5fY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAidG9wNTAgdXAiXSA8LSBtZWFuKGNvdW50c19iYXRjaFtoZWFkX3VwX2dlbmVzLCBjb25kX2JhdGNoPT0iTm9uLXByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIHVwIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbaGVhZF91cF9nZW5lcywgY29uZF9iYXRjaD09IlByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbaGVhZF9kb3duX2dlbmVzLCBjb25kX2JhdGNoPT0iTm9uLXByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIGRvd24iXSA8LSBtZWFuKGNvdW50c19iYXRjaFtoZWFkX2Rvd25fZ2VuZXMsIGNvbmRfYmF0Y2g9PSJQcm9ncmVzc29yIl0pCm1lYW5fY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCBjb25kX2JhdGNoPT0iTm9uLXByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJQcm9ncmVzc29yIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lYW4oY291bnRzX2JhdGNoW2ModGFpbF91cF9nZW5lcywgdGFpbF9kb3duX2dlbmVzKSwgY29uZF9iYXRjaD09IlByb2dyZXNzb3IiXSkKcHJpbnQocm91bmQobWVhbl9jdHNfbWF0LDEpKQoKIyBjaGFuZ2VzIGluIHRlcm1zIG9mIChsb2cpIGZvbGQgY2hhbmdlCmNhdCgiXG4jIyMjIyMgIFJhbmdlIG9mIGZvbGQgY2hhbmdlIGFjcm9zcyBiaW9sb2dpY2FsIGNvbmRpdGlvbnMgICMjIyMjI1xuIikKRkNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz00LCBuY29sPTMsIAogICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygibWluIEZDIiwgIm1lZGlhbiBGQyIsICJtZWFuIEZDIiwgIm1heCBGQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQpGQ19tYXRbLCAidG9wNTAgdXAiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe2ZmKGV4cChkZV9yZXMkdGFibGVbaGVhZF91cF9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICJ0b3A1MCBkb3duIl0gPC0gc2FwcGx5KGMobWluLCBtZWRpYW4sIG1lYW4sIG1heCksIGZ1bmN0aW9uKGZmKXtmZihleHAoZGVfcmVzJHRhYmxlW2hlYWRfZG93bl9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICIxMDAgbGVhc3QgREUiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpewogIGZmKGV4cChkZV9yZXMkdGFibGVbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCAibG9nRkMiXSkpCn0pCnByaW50KHJvdW5kKEZDX21hdCwzKSkKCmNhdCgiXG4jIyMjIyMgIFJhbmdlIG9mIExvZyhmb2xkIGNoYW5nZSkgYWNyb3NzIGJpb2xvZ2ljYWwgY29uZGl0aW9ucyAgIyMjIyMjXG4iKQpsb2dGQ19tYXQgPC0gbG9nKEZDX21hdCkKcm93bmFtZXMobG9nRkNfbWF0KSA8LSBjKCJtaW4gbG9nRkMiLCAibWVkaWFuIGxvZ0ZDIiwgIm1lYW4gbG9nRkMiLCAibWF4IGxvZ0ZDIikKcHJpbnQocm91bmQobG9nRkNfbWF0LDMpKQoKCiMgdmlzdWFsaXplIGNoYW5nZSBpbiB0ZXJtcyBvZiAobG9nKSBmb2xkIGNoYW5nZQpsb2dGQ19kZiA8LSBkYXRhLmZyYW1lKHRvcDUwdXA9ZGVfcmVzJHRhYmxlW2hlYWRfdXBfZ2VuZXMsICJsb2dGQyJdLCB0b3A1MGRvd249ZGVfcmVzJHRhYmxlW2hlYWRfZG93bl9nZW5lcywgImxvZ0ZDIl0pCkZDX2RmIDwtIGV4cChsb2dGQ19kZikKcF9sb2dGQyA8LSBnZ3Bsb3QobWVsdChsb2dGQ19kZiksIGFlcyh4PXZhcmlhYmxlLCB5PXZhbHVlKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKHk9ImxvZ0ZDIikgKwogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpCnBfRkMgPC0gZ2dwbG90KG1lbHQoRkNfZGYpLCBhZXMoeD12YXJpYWJsZSwgeT12YWx1ZSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgbGFicyh5PSJGQyIpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKQpncmlkLmFycmFuZ2UocF9sb2dGQywgcF9GQywgbmNvbD0yKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30Kcm0oY29uZF9iYXRjaCwgY291bnRzX2JhdGNoLCB1cF9nZW5lcywgaGVhZF91cF9nZW5lcywgdGFpbF91cF9nZW5lcywgCiAgIGRvd25fZ2VuZXMsIGhlYWRfZG93bl9nZW5lcywgdGFpbF9kb3duX2dlbmVzLCB5LCBkZXNpZ24sIGZpdCwgcWxmLCBkZV9yZXMsIAogICBtZWFuX2N0c19tYXQsIEZDX21hdCwgcF9GQywgcF9sb2dGQywgRkNfZGYsIGxvZ0ZDX2RmLCBsb2dGQ19tYXQpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBCaW9sb2dpY2FsIGZvbGQgY2hhbmdlIGNvbXBhcmluZyBhdmVyYWdlIGNvdW50cyAqKmluIHRvcCBERSBnZW5lcyoqIGlzIGFib3V0IDEuMi0xLjguIAorIEdlbmUtd2lzZSBmb2xkIGNoYW5nZSAqKmluIHRvcCBERSBnZW5lcyoqIGhhcyBhIHdpZGUgcmFuZ2UgKG1lZGlhbiA0LCBtZWFuIDIxKS4KCgojIyMjIENoYW5nZSBXUlQgYmF0Y2gKCldlIGFyZSBhbHNvIGludGVyZXN0ZWQgdG8gc2VlIGhvdyB0aGUgYXZlcmFnZSAobWVhbikgZ2VuZSBjb3VudHMgY2hhbmdlIGFjcm9zcyBiYXRjaGVzIChpLmUuICoqZGVncmVlIG9mIG1lYW4gYmF0Y2ggZWZmZWN0KiopLiAKClRvIGV4cGxvcmUgdGhpcyBtZWFuIGJhdGNoIGVmZmVjdCwgd2UgKipmaXJzdCBwZXJmb3JtIERFIHdpdGggcmVnYXJkIHRvIHRoZSBiYXRjaCB2YXJpYWJsZSoqLiBUbyBydWxlIG91dCB0aGUgaW1wYWN0IG9mIGJpb2xvZ2ljYWwgY29uZGl0aW9uLCB3ZSBwZXJmb3JtIHRoaXMgYW5hbHlzaXMgd2l0aGluICoqTm9uLXByb2dyZXNzb3JzKiogb25seSwgYW5kIGNvbXBhcmUgKipBZnJpY2EgJiBHNiBzdHVkaWVzKiouIE5vdGUgdGhhdCB0aGlzIERFIGlzIG5vdCB0cnVlIERFIC0gaXQncyB0ZXN0aW5nIGlmIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgbWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIGJhdGNoZXMuIAoKYGBge3IsIHJlc3VsdHM9ImhpZGUifQojIyMjICBEaWZmZXJlbnRpYWwgZ2VuZXMgcmVsYXRpdmUgdG8gYmF0Y2ggCiMjIyMgICh3aXRoaW4gY29uZGl0aW9uIDAgLyBjb25kaXRpb24gc3BlY2lmaWVkIGJ5ICd0ZXN0X2NvbmQnKQpyZHNfc3Vic2V0IDwtIHJkc19vYmpbLCByZHNfb2JqJERhdGFzZXQgJWluJSBjKCJBZnJpY2EiLCAiRzYiKV0KdGVzdF9jb25kIDwtICJOb24tcHJvZ3Jlc3NvciIKY291bnRzX2NvbmQgPC0gYXNzYXkocmRzX3N1YnNldCwgImNvdW50cyIpWywgcmRzX3N1YnNldCRMYWJlbD09dGVzdF9jb25kXQpiYXRjaF9jb25kIDwtIGFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIocmRzX3N1YnNldCRTZXF1ZW5jaW5nQmF0Y2hbcmRzX3N1YnNldCRMYWJlbD09dGVzdF9jb25kXSkpCgp5IDwtIERHRUxpc3QoY291bnRzPWNvdW50c19jb25kLCBncm91cD1hcy5mYWN0b3IoYmF0Y2hfY29uZCkpCnkgPC0gY2FsY05vcm1GYWN0b3JzKHksIG1ldGhvZD0iVE1NIikKZGVzaWduIDwtIG1vZGVsLm1hdHJpeCh+YXMuZmFjdG9yKGJhdGNoX2NvbmQpKQp5IDwtIGVzdGltYXRlRGlzcCh5LCBkZXNpZ24pCmZpdCA8LSBnbG1RTEZpdCh5LCBkZXNpZ24pCnFsZiA8LSBnbG1RTEZUZXN0KGZpdCwgY29lZj0yKQpkZV9yZXMgPC0gdG9wVGFncyhxbGYsIG49bnJvdyhyZHNfc3Vic2V0KSkKCnVwX2dlbmVzIDwtIHJvd25hbWVzKGRlX3JlcylbZGVfcmVzJHRhYmxlJGxvZ0ZDID49IDBdICAjIGFsbCB1cC1yZWd1bGF0ZWQgZ2VuZXMKaGVhZF91cF9nZW5lcyA8LSBoZWFkKHVwX2dlbmVzLCBuPTUwKSAgIyB0b3AtNTAgdXAtcmVndWxhdGVkIGdlbmVzCnRhaWxfdXBfZ2VuZXMgPC0gdGFpbCh1cF9nZW5lcywgbj01MCkgICMgNTAgbGVhc3QgdXAtcmVndWxhdGVkIGdlbmVzCgpiYXRjaF91cF9pbmRzIDwtIHVwX2dlbmVzCgpkb3duX2dlbmVzIDwtIHJvd25hbWVzKGRlX3JlcylbZGVfcmVzJHRhYmxlJGxvZ0ZDIDwgMF0gICMgYWxsIGRvd24tcmVndWxhdGVkIGdlbmVzCmhlYWRfZG93bl9nZW5lcyA8LSBoZWFkKGRvd25fZ2VuZXMsIG49NTApICAjIHRvcC01MCBkb3duLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX2Rvd25fZ2VuZXMgPC0gdGFpbChkb3duX2dlbmVzLCBuPTUwKSAgIyA1MCBsZWFzdCBkb3duLXJlZ3VsYXRlZCBnZW5lcwoKYmF0Y2hfZG93bl9pbmRzIDwtIGRvd25fZ2VuZXMKYGBgCgpgYGB7ciwgZWNobz1GQUxTRX0KIyBjaGFuZ2VzIGluIHRlcm1zIG9mIG1lYW4KY2F0KCIjIyMjIyMgIEJhdGNoIGRpZmZlcmVuY2VzIGluIHRlcm1zIG9mIG1lYW4gZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVhbl9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQWZyaWNhIiwgIkc2IiksIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IGNoYW5nZWQiKSkpCm1lYW5fY3RzX21hdFsiQWZyaWNhIiwgInRvcDUwIHVwIl0gPC0gbWVhbihjb3VudHNfY29uZFtoZWFkX3VwX2dlbmVzLCBiYXRjaF9jb25kPT0iQWZyaWNhIl0pCm1lYW5fY3RzX21hdFsiRzYiLCAidG9wNTAgdXAiXSA8LSBtZWFuKGNvdW50c19jb25kW2hlYWRfdXBfZ2VuZXMsIGJhdGNoX2NvbmQ9PSJHNiJdKQptZWFuX2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihjb3VudHNfY29uZFtoZWFkX2Rvd25fZ2VuZXMsIGJhdGNoX2NvbmQ9PSJBZnJpY2EiXSkKbWVhbl9jdHNfbWF0WyJHNiIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihjb3VudHNfY29uZFtoZWFkX2Rvd25fZ2VuZXMsIGJhdGNoX2NvbmQ9PSJHNiJdKQptZWFuX2N0c19tYXRbIkFmcmljYSIsICIxMDAgbGVhc3QgY2hhbmdlZCJdIDwtIG1lYW4oY291bnRzX2NvbmRbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCBiYXRjaF9jb25kPT0iQWZyaWNhIl0pCm1lYW5fY3RzX21hdFsiRzYiLCAiMTAwIGxlYXN0IGNoYW5nZWQiXSA8LSBtZWFuKGNvdW50c19jb25kW2ModGFpbF91cF9nZW5lcywgdGFpbF9kb3duX2dlbmVzKSwgYmF0Y2hfY29uZD09Ikc2Il0pCnByaW50KHJvdW5kKG1lYW5fY3RzX21hdCwyKSkKCiMgY2hhbmdlcyBpbiB0ZXJtcyBvZiBmb2xkIGNoYW5nZQpjYXQoIlxuIyMjIyMjICBSYW5nZSBvZiBmb2xkIGNoYW5nZSBiZXR3ZWVuIGJhdGNoZXMgICMjIyMjI1xuIikKY2F0KCItIEFsbCBnZW5lcyAtIEZDOlxuIikKY2F0KHJvdW5kKHJhbmdlKGV4cChkZV9yZXMkdGFibGUkbG9nRkMpKSwgMykpIAoKY2F0KCJcblxuLSBBbGwgZ2VuZXMgLSBsb2coRkMpOlxuIikKY2F0KHJvdW5kKHJhbmdlKGRlX3JlcyR0YWJsZSRsb2dGQyksIDMpKSAKCmNhdCgiXG5cbi0gVG9wIGdlbmVzIC0gRkM6XG4iKQpGQ19tYXQgPC0gbWF0cml4KE5BLCBucm93PTQsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChjKCJtaW4gRkMiLCAibWVkaWFuIEZDIiwgIm1lYW4gRkMiLCAibWF4IEZDIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygidG9wNTAgdXAiLCAidG9wNTAgZG93biIsICIxMDAgbGVhc3QgREUiKSkpCkZDX21hdFssICJ0b3A1MCB1cCJdIDwtIHNhcHBseShjKG1pbiwgbWVkaWFuLCBtZWFuLCBtYXgpLCBmdW5jdGlvbihmZil7ZmYoZXhwKGRlX3JlcyR0YWJsZVtoZWFkX3VwX2dlbmVzLCAibG9nRkMiXSkpfSkKRkNfbWF0WywgInRvcDUwIGRvd24iXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe2ZmKGV4cChkZV9yZXMkdGFibGVbaGVhZF9kb3duX2dlbmVzLCAibG9nRkMiXSkpfSkKRkNfbWF0WywgIjEwMCBsZWFzdCBERSJdIDwtIHNhcHBseShjKG1pbiwgbWVkaWFuLCBtZWFuLCBtYXgpLCBmdW5jdGlvbihmZil7CiAgZmYoZXhwKGRlX3JlcyR0YWJsZVtjKHRhaWxfdXBfZ2VuZXMsIHRhaWxfZG93bl9nZW5lcyksICJsb2dGQyJdKSkKfSkKcHJpbnQocm91bmQoRkNfbWF0LDMpKQoKY2F0KCJcbi0gVG9wIGdlbmVzIC0gbG9nKEZDKTpcbiIpCmxvZ0ZDX21hdCA8LSBsb2coRkNfbWF0KQpyb3duYW1lcyhsb2dGQ19tYXQpIDwtIGMoIm1pbiBsb2dGQyIsICJtZWRpYW4gbG9nRkMiLCAibWVhbiBsb2dGQyIsICJtYXggbG9nRkMiKQpwcmludChyb3VuZChsb2dGQ19tYXQsMykpCgpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30Kcm0oYmF0Y2hfY29uZCwgY291bnRzX2NvbmQsIHVwX2dlbmVzLCBoZWFkX3VwX2dlbmVzLCB0YWlsX3VwX2dlbmVzLCAKICAgZG93bl9nZW5lcywgaGVhZF9kb3duX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMsIHksIGRlc2lnbiwgZml0LCBxbGYsIGRlX3JlcywgCiAgIG1lYW5fY3RzX21hdCwgRkNfbWF0LCBsb2dGQ19tYXQpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBNZWFuIGJhdGNoIGVmZmVjdCBmb2xkIGNoYW5nZSBjb21wYXJpbmcgYXZlcmFnZSBjb3VudHMgKippbiB0b3AgZ2VuZXMqKiByYW5nZXMgZnJvbSAxLjE4LTMuNTYuICoqUmVtZW1iZXIgdGhhdCB0aGVzZSBhcmUgZ2VuZXMgbW9zdCBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBhY3Jvc3MgYmF0Y2gqKi4KKyBHZW5lLXdpc2UgbWVhbiBiYXRjaCBlZmZlY3QgZm9sZCBjaGFuZ2UgKippbiB0b3AgZ2VuZXMqKiBoYXMgYSB3aWRlIHJhbmdlIChtZWFuIDQuNCwgbWVkaWFuIDUyLjYpLgoKCiMjIyBCYXRjaCBtZWFuCgoqKk1lZGlhbiAob2YgYWxsIGdlbmVzKSoqIGdlbmUtd2lzZSBtZWFuOiAKCmBgYHtyLCBlY2hvPUZBTFNFfQptZWFuX3RiIDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiTm9uLXByb2dyZXNzb3IiLCAiUHJvZ3Jlc3NvciIpLCBjKCJBZnJpY2EiLCAiRzYiLCAiQnJhemlsMSIpKSkKbWVhbl90YlsiTm9uLXByb2dyZXNzb3IiLCAiQWZyaWNhIl0gPC0gbWVkaWFuKHJvd01lYW5zKGN0c1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQptZWFuX3RiWyJQcm9ncmVzc29yIiwgIkFmcmljYSJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNbLCBiYXRjaD09IkFmcmljYSImZ3JvdXA9PSJQcm9ncmVzc29yIl0pKQptZWFuX3RiWyJOb24tcHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNbLCBiYXRjaD09Ikc2IiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQptZWFuX3RiWyJQcm9ncmVzc29yIiwgIkc2Il0gPC0gbWVkaWFuKHJvd01lYW5zKGN0c1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdKSkKbWVhbl90YlsiTm9uLXByb2dyZXNzb3IiLCAiQnJhemlsMSJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNbLCBiYXRjaD09IkJyYXppbF8xIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQptZWFuX3RiWyJQcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzWywgYmF0Y2g9PSJCcmF6aWxfMSImZ3JvdXA9PSJQcm9ncmVzc29yIl0pKQpwcmludChyb3VuZChtZWFuX3RiLCAyKSkKYGBgCgpTY2FsZWQgYnkgdGhhdCBvZiBBZnJpY2E6CgpgYGB7ciwgZWNobz1GQUxTRX0KbWVhbl90Yl9zY2FsZWQgPC0gYXBwbHkobWVhbl90YiwgMiwgZnVuY3Rpb24oeCl7eC9tZWFuX3RiWywiQWZyaWNhIl19KQpwcmludChyb3VuZChtZWFuX3RiX3NjYWxlZCwgMikpCmBgYAoKCiMjIyBCYXRjaCBkaXNwZXJzaW9uCgpBc2lkZSBmcm9tIGF2ZXJhZ2UgZ2VuZSBjb3VudHMsIHdlIGFyZSBpbnRlcmVzdGVkIGluIGNvbXBhcmluZyBkaXNwZXJzaW9ucyBpbiB0aGUgYmF0Y2hlcy4gKipEaWZmZXJlbmNlIGluIHRoZSBkaXNwZXJzaW9ucyBhY3Jvc3MgYmF0Y2hlcyBzdWdnZXN0cyB2YXJpYW5jZSBiYXRjaCBlZmZlY3Qgbm90IGFjY291bnRlZCBmb3IgYnkgUG9pc3NvbiBtb2RlbCoqLiBXZSB2aXN1YWxpemUgdGhlIGdlbmUtd2lzZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBmcm9tIGVkZ2VSOgoKYGBge3IsIGVjaG89RkFMU0V9CiMjIyMgIERpc3BlcnNpb24gZGlmZmVyZW5jZXMgYWNyb3NzIGJhdGNoZXMgCnlfYmF0Y2gxIDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJBZnJpY2EiXSwgZ3JvdXA9YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cFtiYXRjaD09IkFmcmljYSJdKSkpCnlfYmF0Y2gxIDwtIGNhbGNOb3JtRmFjdG9ycyh5X2JhdGNoMSwgbWV0aG9kPSJUTU0iKQpkZXNpZ25fYmF0Y2gxIDwtIG1vZGVsLm1hdHJpeCh+YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cFtiYXRjaD09IkFmcmljYSJdKSkpCnlfYmF0Y2gxIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMSwgZGVzaWduX2JhdGNoMSkKCnlfYmF0Y2gyIDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJHNiJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iRzYiXSkpKQp5X2JhdGNoMiA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDIsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoMiA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PSJHNiJdKSkpCnlfYmF0Y2gyIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMiwgZGVzaWduX2JhdGNoMikKCnlfYmF0Y2gzIDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJJbmRpYSJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iSW5kaWEiXSkpKQp5X2JhdGNoMyA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDMsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoMyA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PSJJbmRpYSJdKSkpCnlfYmF0Y2gzIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMywgZGVzaWduX2JhdGNoMykKCnlfYmF0Y2g0IDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJCcmF6aWxfMSJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iQnJhemlsXzEiXSkpKQp5X2JhdGNoNCA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDQsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoNCA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PSJCcmF6aWxfMSJdKSkpCnlfYmF0Y2g0IDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoNCwgZGVzaWduX2JhdGNoNCkKCnlfYmF0Y2g1IDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJCcmF6aWxfMiJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iQnJhemlsXzIiXSkpKQp5X2JhdGNoNSA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDUsIG1ldGhvZD0iVE1NIikKI2Rlc2lnbl9iYXRjaDUgPC0gbW9kZWwubWF0cml4KH5hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iQnJhemlsXzIiXSkpKQp5X2JhdGNoNSA8LSBlc3RpbWF0ZURpc3AoeV9iYXRjaDUpCgpkaXNwX2RmIDwtIGRhdGEuZnJhbWUoQWZyaWNhPXlfYmF0Y2gxJHRhZ3dpc2UuZGlzcGVyc2lvbiwgRzY9eV9iYXRjaDIkdGFnd2lzZS5kaXNwZXJzaW9uLCAKICAgICAgICAgICAgICAgICAgICAgIEluZGlhPXlfYmF0Y2gzJHRhZ3dpc2UuZGlzcGVyc2lvbiwgQnJhemlsXzE9eV9iYXRjaDQkdGFnd2lzZS5kaXNwZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgQnJhemlsXzI9eV9iYXRjaDUkdGFnd2lzZS5kaXNwZXJzaW9uKQoKY2F0KCIjIyMjICBTdGF0aXN0aWNzIGFib3V0IGRpc3BlcnNpb24gZXN0aW1hdGVzIGZyb20gdGhlIHR3byBiYXRjaGVzICAjIyMjXG4iKQpkaXNwX3N0YXRzIDwtIGxhcHBseShjKG1pbiwgbWVkaWFuLCBtZWFuLCBtYXgpLCBmdW5jdGlvbihmZil7YXBwbHkoZGlzcF9kZiwgMiwgZmYpfSkKZGlzcF9zdGF0cyA8LSBkby5jYWxsKHJiaW5kLCBkaXNwX3N0YXRzKQpyb3duYW1lcyhkaXNwX3N0YXRzKSA8LSBjKCJtaW4gZGlzcC4iLCAibWVkaWFuIGRpc3AuIiwgIm1lYW4gZGlzcC4iLCAibWF4IGRpc3AuIikKcHJpbnQocm91bmQoZGlzcF9zdGF0cywgNCkpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRpc3BfZGZfbWx0IDwtIG1lbHQoZGlzcF9kZikKZ2dwbG90KGRpc3BfZGZfbWx0LCBhZXMoeD12YXJpYWJsZSwgeT12YWx1ZSkpICsKICBnZW9tX3Zpb2xpbigpICsKICBsYWJzKHg9IkJhdGNoIiwgeT0iRXN0aW1hdGVkIGdlbmUtd2lzZSBkaXNwZXJzaW9uIiwgCiAgICAgICB0aXRsZT0iQ29tcGFyaXNvbiBvZiBlc3RpbWF0ZWQgZGlzcGVyc2lvbiBhY3Jvc3MgYmF0Y2hlcyIpICsKICBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgY29sb3VyPSJkYXJrcmVkIiwgZ2VvbT0icG9pbnQiLCBzaGFwZT0xOCwgc2l6ZT0zKSAjKwogICNzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgMSkpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBNZWFuIGRpc3BlcnNpb24gaW4gdGhlIEFmcmljYSAvIEJhdGNoIDEgaW4gdGhlIEJyYXppbCBzdHVkeSBpcyBhYm91dCAxMCB0aW1lcyBvZiB0aG9zZSBpbiB0aGUgSW5kaWEgc3R1ZHkuIAorIFdlIHNlZSBodWdlIG1heCBnZW5lLXdpc2UgZGlzcGVyc2lvbnMsIHBvc3NpYmx5IGNhdXNlZCBieSAwIGNvdW50cy4KCgojIyMgQmF0Y2ggdmFyaWFuY2UKCioqTWVkaWFuIChvZiBhbGwgZ2VuZXMpKiogZ2VuZS13aXNlIHZhcmlhbmNlOiAKCmBgYHtyLCBlY2hvPUZBTFNFfQp2YXJfdGIgPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChjKCJOb24tcHJvZ3Jlc3NvciIsICJQcm9ncmVzc29yIiksIGMoIkFmcmljYSIsICJHNiIsICJCcmF6aWwxIikpKQp2YXJfdGJbIk5vbi1wcm9ncmVzc29yIiwgIkFmcmljYSJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQp2YXJfdGJbIlByb2dyZXNzb3IiLCAiQWZyaWNhIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzWywgYmF0Y2g9PSJBZnJpY2EiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdKSkKdmFyX3RiWyJOb24tcHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSkpCnZhcl90YlsiUHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdKSkKdmFyX3RiWyJOb24tcHJvZ3Jlc3NvciIsICJCcmF6aWwxIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzWywgYmF0Y2g9PSJCcmF6aWxfMSImZ3JvdXA9PSJOb24tcHJvZ3Jlc3NvciJdKSkKdmFyX3RiWyJQcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNbLCBiYXRjaD09IkJyYXppbF8xIiZncm91cD09IlByb2dyZXNzb3IiXSkpCnByaW50KHJvdW5kKHZhcl90YiwgMikpCmBgYAoKU2NhbGVkIGJ5IHRoYXQgb2YgQWZyaWNhOgoKYGBge3IsIGVjaG89RkFMU0V9CnZhcl90Yl9zY2FsZWQgPC0gYXBwbHkodmFyX3RiLCAyLCBmdW5jdGlvbih4KXt4L3Zhcl90YlssIkFmcmljYSJdfSkKcHJpbnQocm91bmQodmFyX3RiX3NjYWxlZCwgMikpCmBgYAoKCiMjIEltcGFjdCBvZiAwIGNvdW50cyBvbiBnZW5lIGRpc3RyaWJ1dGlvbnMKCldlIGhhdmUgc2VlbiBhYm92ZSB0aGF0IG92ZXIgaGFsZiBvZiBnZW5lcyBpbiB0aGUgZGF0YXNldCBjb250YWluIHNvbWUgcG9ydGlvbnMgb2YgemVyb3MuIEhhdmluZyAwIGNvdW50cyBjYW4gaGF2ZSBhIGdvb2QgaW1wYWN0IG9uIG1lYW4gYW5kIGRpc3BlcnNpb24gZXN0aW1hdGlvbi4gV2UgZXZhbHVhdGUgc3VjaCBpbXBhY3QgaW4gdGhpcyBzZWN0aW9uLCBhbmQgc2VlIGhvdyBOQiBkaXN0cmlidXRpb24gZml0cyB0byBub24temVybyBwb3J0aW9uIG9mIGdlbmVzLiBXZSBmaXJzdCB0YWtlIHRoZSBub24temVybyBwb3J0aW9uIG9mIHRoZSBnZW5lcy4KCiMjIyBGb2xkIGNoYW5nZSBpbiBtZWFuIGluIG5vbi16ZXJvIHBvcnRpb24gey50YWJzZXR9CgpgYGB7ciwgZWNobz1GQUxTRX0KIyB0YWtlIHRoZSBub24temVybyBwb3J0aW9uIGluIGVhY2ggZ2VuZQpiYXRjaF9zZXAgPC0gZ3JvdXBfc2VwIDwtIG5vbnplcm9fY3RzIDwtIHN0dWRpZXNfc2VwIDwtIGxpc3QoKQpmb3IoaSBpbiAxOm5yb3coY3RzKSl7CiAgbm9uemVyb19pbmQgPC0gd2hpY2goY3RzW2ksIF0hPTApCiAgYmF0Y2hfc2VwW1tpXV0gPC0gYXMuY2hhcmFjdGVyKGJhdGNoW25vbnplcm9faW5kXSkKICBncm91cF9zZXBbW2ldXSA8LSBhcy5jaGFyYWN0ZXIoZ3JvdXBbbm9uemVyb19pbmRdKQogIG5vbnplcm9fY3RzW1tpXV0gPC0gY3RzW2ksIG5vbnplcm9faW5kXQogIHN0dWRpZXNfc2VwW1tpXV0gPC0gYXMuY2hhcmFjdGVyKHJkc19vYmokRGF0YXNldFtub256ZXJvX2luZF0pCn0KIyBzYW5pdHkgY2hlY2sKaWYoIWlkZW50aWNhbChzYXBwbHkobm9uemVyb19jdHMsIGxlbmd0aCksIGFzLmludGVnZXIocm93U3VtcyhjdHMhPTApKSkpe3N0b3AoIkVycm9yIGluIHRha2luZyBub24temVybyBwb3J0aW9ucyEiKX0KCm5hbWVzKG5vbnplcm9fY3RzKSA8LSByb3duYW1lcyhjdHMpOyBuYW1lcyhiYXRjaF9zZXApIDwtIHJvd25hbWVzKGN0cyk7IG5hbWVzKGdyb3VwX3NlcCkgPC0gcm93bmFtZXMoY3RzKQpgYGAKCiMjIyMgIENoYW5nZSBXUlQgY29uZGl0aW9uIGluIEc2CgpXaXRoaW4gKipHNioqLCB3ZSBjb21wYXJlIG1lYW4gKGhlcmUgcmVmZXJzIHRvIG5vbi16ZXJvIG1lYW4pIGFjcm9zcyBiaW9sb2dpY2FsIGNvbmRpdGlvbiBncm91cHMuIFNwZWNpZmljYWxseSwgKip3ZSBzYXZlZCB0aGUgcHJldmlvdXMgREUgYW5hbHlzaXMgcmVzdWx0cyB1c2luZyBlZGdlUiwgb24gY291bnRzIGNvbnRhaW5pbmcgemVyb3MqKi4gV2UgY2FsbCBhbGwgZ2VuZXMgd2l0aCAkXGxvZyhGQykgPj0gMCQgYXMgInVwIiBnZW5lcywgYW5kICRcbG9nKEZDKSA8IDAkIGFzICJkb3duIiBnZW5lcy4gVGhlIHRvcCA1MCAidXAiIGFuZCAiZG93biIgZ2VuZXMgYXJlIHN0aWxsIGRldGVybWluZWQgYnkgdGhlIHByZXZpb3VzIERFIGNvbnRhaW5pbmcgemVyb3MuIAoKYGBge3IsIGVjaG89RkFMU0V9CiMgdGFrZSBHNgpncm91cF9zZXBfYmF0Y2gxIDwtIG5vbnplcm9fY3RzX2JhdGNoMSA8LSBsaXN0KCkKZm9yKGkgaW4gMTpsZW5ndGgobm9uemVyb19jdHMpKXsKICBncm91cF9zZXBfYmF0Y2gxW1tpXV0gPC0gZ3JvdXBfc2VwW1tpXV1bYmF0Y2hfc2VwW1tpXV09PSJHNiJdCiAgbm9uemVyb19jdHNfYmF0Y2gxW1tpXV0gPC0gbm9uemVyb19jdHNbW2ldXVtiYXRjaF9zZXBbW2ldXT09Ikc2Il0KfQpuYW1lcyhub256ZXJvX2N0c19iYXRjaDEpIDwtIG5hbWVzKGdyb3VwX3NlcF9iYXRjaDEpIDwtIHJvd25hbWVzKGN0cykKCiMgc3BsaXQgaW50byBjb250cm9scyAmIGNhc2VzCm5vbnplcm9fY3RzX2IxX2N0cmxzIDwtIG5vbnplcm9fY3RzX2IxX2Nhc2VzIDwtIGxpc3QoKQpmb3IoaiBpbiAxOmxlbmd0aChub256ZXJvX2N0c19iYXRjaDEpKXsKICBub256ZXJvX2N0c19iMV9jdHJsc1tbal1dIDwtIG5vbnplcm9fY3RzX2JhdGNoMVtbal1dW2dyb3VwX3NlcF9iYXRjaDFbW2pdXT09Ik5vbi1wcm9ncmVzc29yIl0KICBub256ZXJvX2N0c19iMV9jYXNlc1tbal1dIDwtIG5vbnplcm9fY3RzX2JhdGNoMVtbal1dW2dyb3VwX3NlcF9iYXRjaDFbW2pdXT09IlByb2dyZXNzb3IiXQp9I2lkZW50aWNhbChzYXBwbHkobm9uemVyb19jdHNfYjFfY3RybHMsIGxlbmd0aCkgKyBzYXBwbHkobm9uemVyb19jdHNfYjFfY2FzZXMsIGxlbmd0aCksIHNhcHBseShub256ZXJvX2N0c19iYXRjaDEsbGVuZ3RoKSkKbmFtZXMobm9uemVyb19jdHNfYjFfY3RybHMpIDwtIG5hbWVzKG5vbnplcm9fY3RzX2IxX2Nhc2VzKSA8LSByb3duYW1lcyhjdHMpCgojIHRvcCA1MCB1cCBhbmQgZG93biBpbmRpY2VzCnRvcF91cF9pbmQgPC0gaGVhZChjb25kX3VwX2luZHMsIDUwKQp0b3BfZG93bl9pbmQgPC0gaGVhZChjb25kX2Rvd25faW5kcywgNTApCmxlYXN0X2RlX2luZCA8LSBjKHRhaWwoY29uZF91cF9pbmRzLCA1MCksIHRhaWwoY29uZF9kb3duX2luZHMsIDUwKSkKCiMgY2FsY3VsYXRlIG1lYW4gaW4gdG9wIHVwLCBkb3duIGFuZCBsZWFzdCBERQpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiBNRUFOIG5vbi16ZXJvIGdlbmUgY291bnRzICAjIyMjIyNcbiIpCm1lYW5fbm9uemVyb2N0c19tYXQgPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiTm9uLXByb2dyZXNzb3IiLCAiUHJvZ3Jlc3NvciIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBERSIpKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAidG9wNTAgdXAiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjFfY3RybHNbdG9wX3VwX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIHVwIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW3RvcF91cF9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jdHJsc1t0b3BfZG93bl9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiUHJvZ3Jlc3NvciIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW3RvcF9kb3duX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjFfY3RybHNbbGVhc3RfZGVfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIlByb2dyZXNzb3IiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW2xlYXN0X2RlX2luZF0pKQpwcmludChyb3VuZChtZWFuX25vbnplcm9jdHNfbWF0LDEpKQpgYGAKCmBgYHtyLGVjaG89RkFMU0V9CmNhdCgiIyMjIyMjICBDaGFuZ2VzIGluIE1FRElBTiBub24temVybyBnZW5lIGNvdW50cyAgIyMjIyMjXG4iKQptZWRpYW5fbm9uemVyb2N0c19tYXQgPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiTm9uLXByb2dyZXNzb3IiLCAiUHJvZ3Jlc3NvciIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBERSIpKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICJ0b3A1MCB1cCJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2N0cmxzW3RvcF91cF9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIHVwIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjFfY2FzZXNbdG9wX3VwX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIk5vbi1wcm9ncmVzc29yIiwgInRvcDUwIGRvd24iXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jdHJsc1t0b3BfZG93bl9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIGRvd24iXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jYXNlc1t0b3BfZG93bl9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jdHJsc1tsZWFzdF9kZV9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW2xlYXN0X2RlX2luZF0pKQpwcmludChyb3VuZChtZWRpYW5fbm9uemVyb2N0c19tYXQsMSkpCmBgYAoKKipDb25jbHVzaW9uczogKiogCgorIEJpb2xvZ2ljYWwgZm9sZCBjaGFuZ2UgKGluIG5vbi16ZXJvIHBvcnRpb24pIGNvbXBhcmluZyBhdmVyYWdlIGNvdW50cyAqKmluIHRvcCBnZW5lcyoqIGlzIGFib3V0IDEuMi0xLjggKG1lYW4pLgorIE8gY291bnRzIGRpZCBub3Qgc3Ryb25nbHkgYWZmZWN0IGJpb2xvZ2ljYWwgc2lnbmFsIGluIHRlcm1zIG9mIGF2ZXJhZ2UgY291bnRzICoqaW4gdG9wIGdlbmVzKiogLgoKCiMjIyMgIENoYW5nZSBXUlQgYmF0Y2ggaW4gbm9uLXByb2dyZXNzb3JzCgpTaW1pbGFybHksIHdlIGNvbXBhcmUgbm9uLXplcm8gbWVhbiAqKmluIHRvcCBnZW5lcyoqIGFjcm9zcyBiYXRjaGVzIHdpdGhpbiAiTm9uLXByb2dyZXNzb3JzIiBvZiBBZnJpY2EgYW5kIEc2IHN0dWRpZXMuIEhlcmUg4oCcdG9wIGdlbmVz4oCdIHJlZmVyIHRvIHRvcCBnZW5lIGxpc3RzIGZyb20gcHJldmlvdXMgREUgd2l0aGluIGNvbnRyb2wgc2FtcGxlcyBjb21wYXJpbmcgYmF0Y2hlcy4KCmBgYHtyLCBlY2hvPUZBTFNFfQojIHRha2UgY29udHJvbHMKYmF0Y2hfc2VwX2NvbmQwIDwtIG5vbnplcm9fY3RzX2NvbmQwIDwtIGxpc3QoKQpmb3IoaSBpbiAxOmxlbmd0aChub256ZXJvX2N0cykpewogIGJhdGNoX3NlcF9jb25kMFtbaV1dIDwtIGJhdGNoX3NlcFtbaV1dW2dyb3VwX3NlcFtbaV1dPT0iTm9uLXByb2dyZXNzb3IiXQogIG5vbnplcm9fY3RzX2NvbmQwW1tpXV0gPC0gbm9uemVyb19jdHNbW2ldXVtncm91cF9zZXBbW2ldXT09Ik5vbi1wcm9ncmVzc29yIl0KfQpuYW1lcyhiYXRjaF9zZXBfY29uZDApIDwtIG5hbWVzKG5vbnplcm9fY3RzX2NvbmQwKSA8LSByb3duYW1lcyhjdHMpCgojIHNwbGl0IGludG8gYmF0Y2ggMSAmIDIKbm9uemVyb19jdHNfY29uZDBfYmF0Y2gxIDwtIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMiA8LSBsaXN0KCkKZm9yKGogaW4gMTpsZW5ndGgobm9uemVyb19jdHMpKXsKICBub256ZXJvX2N0c19jb25kMF9iYXRjaDFbW2pdXSA8LSBub256ZXJvX2N0c19jb25kMFtbal1dW2JhdGNoX3NlcF9jb25kMFtbal1dPT0iQWZyaWNhIl0KICBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbW2pdXSA8LSBub256ZXJvX2N0c19jb25kMFtbal1dW2JhdGNoX3NlcF9jb25kMFtbal1dPT0iRzYiXQp9Cm5hbWVzKG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMSkgPC0gbmFtZXMobm9uemVyb19jdHNfY29uZDBfYmF0Y2gyKSA8LSByb3duYW1lcyhjdHMpCgojIHRvcCA1MCB1cCBhbmQgZG93biBpbmRpY2VzCnRvcF91cF9pbmQgPC0gaGVhZChiYXRjaF91cF9pbmRzLCA1MCkKdG9wX2Rvd25faW5kIDwtIGhlYWQoYmF0Y2hfZG93bl9pbmRzLCA1MCkKbGVhc3RfZGVfaW5kIDwtIGModGFpbChiYXRjaF91cF9pbmRzLCA1MCksIHRhaWwoYmF0Y2hfZG93bl9pbmRzLCA1MCkpCgojIGNhbGN1bGF0ZSBtZWFuIGluIHRvcCB1cCwgZG93biBhbmQgbGVhc3QgREUKY2F0KCIjIyMjIyMgIENoYW5nZXMgaW4gTUVBTiBub24temVybyBnZW5lIGNvdW50cyAgIyMjIyMjXG4iKQptZWFuX25vbnplcm9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIkFmcmljYSIsICJHNiIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBERSIpKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiQWZyaWNhIiwgInRvcDUwIHVwIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVt0b3BfdXBfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkc2IiwgInRvcDUwIHVwIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMlt0b3BfdXBfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVt0b3BfZG93bl9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiRzYiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX2Rvd25faW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gxW2xlYXN0X2RlX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJHNiIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gyW2xlYXN0X2RlX2luZF0pKQpwcmludChyb3VuZChtZWFuX25vbnplcm9jdHNfbWF0LDEpKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQojIGNhbGN1bGF0ZSBtZWRpYW4gaW4gdG9wIHVwLCBkb3duIGFuZCBsZWFzdCBERQpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiBNRURJQU4gbm9uLXplcm8gZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVkaWFuX25vbnplcm9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQWZyaWNhIiwgIkc2IiksIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCB1cCJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVt0b3BfdXBfaW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiRzYiLCAidG9wNTAgdXAiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX3VwX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCBkb3duIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gxW3RvcF9kb3duX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkc2IiwgInRvcDUwIGRvd24iXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX2Rvd25faW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiQWZyaWNhIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVtsZWFzdF9kZV9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJHNiIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbbGVhc3RfZGVfaW5kXSkpCnByaW50KHJvdW5kKG1lZGlhbl9ub256ZXJvY3RzX21hdCwxKSkKYGBgCgoqKkNvbmNsdXNpb25zOioqIAoKKyBNZWFuIGJhdGNoIGVmZmVjdCBmb2xkIGNoYW5nZSAobm9uLXplcm8gcG9ydGlvbikgY29tcGFyaW5nIGF2ZXJhZ2UgY291bnRzICoqaW4gdG9wIGdlbmVzKiogcmFuZ2VzIGZyb20gMS4xNi0zLjMgKG1lYW4pLiAKKyBPIGNvdW50cyBkaWQgbm90IHN0cm9uZ2x5IGFmZmVjdCBtZWFuIGJhdGNoIGVmZmVjdCBpbiB0ZXJtcyBvZiBhdmVyYWdlIGNvdW50cyAqKmluIHRvcCBnZW5lcyoqLgoKCiMjIyBCYXRjaCBtZWFuIHdpdGggMCBjb3VudHMgcmVtb3ZlZCAKCioqTWVkaWFuIChvZiBhbGwgZ2VuZXMpKiogZ2VuZS13aXNlIG1lYW4gYWZ0ZXIgcmVtb3ZpbmcgemVyb3M6IAoKYGBge3IsIGVjaG89RkFMU0V9Cm1lYW5fdGJfcm16ZXJvIDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIk5vbi1wcm9ncmVzc29yIiwgIlByb2dyZXNzb3IiKSwgYygiQWZyaWNhIiwgIkc2IiwgIkJyYXppbDEiKSkpCmN0c19ybXplcm8gPC0gY3RzOyBjdHNfcm16ZXJvW2N0c19ybXplcm89PTBdIDwtIE5BCm1lYW5fdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJBZnJpY2EiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQptZWFuX3RiX3JtemVyb1siUHJvZ3Jlc3NvciIsICJBZnJpY2EiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09IlByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCm1lYW5fdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNfcm16ZXJvWywgYmF0Y2g9PSJHNiImZ3JvdXA9PSJOb24tcHJvZ3Jlc3NvciJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKbWVhbl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiRzYiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKbWVhbl90Yl9ybXplcm9bIk5vbi1wcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQnJhemlsXzEiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCm1lYW5fdGJfcm16ZXJvWyJQcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQnJhemlsXzEiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKcHJpbnQocm91bmQobWVhbl90Yl9ybXplcm8sIDIpKQpgYGAKClNjYWxlZCBieSB0aGF0IG9mIEFmcmljYToKCmBgYHtyLCBlY2hvPUZBTFNFfQptZWFuX3RiX3JtemVyb19zY2FsZWQgPC0gYXBwbHkobWVhbl90Yl9ybXplcm8sIDIsIGZ1bmN0aW9uKHgpe3gvbWVhbl90Yl9ybXplcm9bLCJBZnJpY2EiXX0pCnByaW50KHJvdW5kKG1lYW5fdGJfcm16ZXJvX3NjYWxlZCwgMikpCmBgYAoKCiMjIyBCYXRjaCBkaXNwZXJzaW9uIHdpdGggMCBjb3VudHMgcmVtb3ZlZCAKCkRpc3BlcnNpb24gZXN0aW1hdGVzIGFyZSBtb3JlIGxpa2VseSBpbXBhY3RlZCBieSAwIGNvdW50cy4gV2UgcmUtZXN0aW1hdGUgdGhlIGRpc3BlcnNpb25zIGluIGVhY2ggYmF0Y2gsIHVzaW5nIG5vbi16ZXJvIHBvcnRpb24gb2YgZWFjaCBnZW5lLiBUaGVuIHdlIGNvbXBhcmUgdGhlIGRpc3BlcnNpb24gZXN0aW1hdGVzIGFjcm9zcyBiYXRjaGVzLgoKYGBge3IsIGVjaG89RkFMU0V9CmxvYWQoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJkaXNwc19ub256ZXJvLlJEYXRhIikpCmRpc3Bfbm9uemVyb19sc3QgPC0gbGlzdChBZnJpY2E9ZGlzcF9ub256ZXJvX2FmcmljYSwgRzY9ZGlzcF9ub256ZXJvX0c2LAogICAgICAgICAgICAgICAgICAgICAgICAgSW5kaWE9ZGlzcF9ub256ZXJvX2luZGlhLCBCcmF6aWxfMT1kaXNwX25vbnplcm9fYnpsMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBCcmF6aWxfMj1kaXNwX25vbnplcm9fYnpsMikKY2F0KCIjIyMjICBTdGF0aXN0aWNzIGFib3V0IGRpc3BlcnNpb24gZXN0aW1hdGVzIChmcm9tIE5PTi1aRVJPIHBvcnRpb25zKSBmcm9tIHRoZSB0d28gYmF0Y2hlcyAgIyMjI1xuIikKZGlzcF9zdGF0cyA8LSBsYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe3NhcHBseShkaXNwX25vbnplcm9fbHN0LCBmZil9KQpkaXNwX3N0YXRzIDwtIGRvLmNhbGwocmJpbmQsIGRpc3Bfc3RhdHMpCnJvd25hbWVzKGRpc3Bfc3RhdHMpIDwtIGMoIm1pbiBkaXNwLiIsICJtZWRpYW4gZGlzcC4iLCAibWVhbiBkaXNwLiIsICJtYXggZGlzcC4iKQpwcmludChyb3VuZChkaXNwX3N0YXRzLCA0KSkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZGlzcF9ub256ZXJvX2RmIDwtIGRhdGEuZnJhbWUoQmF0Y2g9YyhyZXAoIkFmcmljYSIsIGxlbmd0aChkaXNwX25vbnplcm9fYWZyaWNhKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcCgiRzYiLCBsZW5ndGgoZGlzcF9ub256ZXJvX0c2KSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJJbmRpYSIsIGxlbmd0aChkaXNwX25vbnplcm9faW5kaWEpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXAoIkJyYXppbF8xIiwgbGVuZ3RoKGRpc3Bfbm9uemVyb19iemwxKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJCcmF6aWxfMiIsIGxlbmd0aChkaXNwX25vbnplcm9fYnpsMikpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9ZG8uY2FsbChjLCBkaXNwX25vbnplcm9fbHN0KSkKZ2dwbG90KGRpc3Bfbm9uemVyb19kZiAsIGFlcyh4PUJhdGNoLCB5PXZhbHVlKSkgKwogIGdlb21fdmlvbGluKCkgKwogIGxhYnMoeD0iQmF0Y2giLCB5PSJFc3RpbWF0ZWQgZ2VuZS13aXNlIGRpc3BlcnNpb24gb24gTk9OLVpFUk8gY291bnRzIiwgCiAgICAgICB0aXRsZT0iQ29tcGFyaXNvbiBvZiBlc3RpbWF0ZWQgZGlzcGVyc2lvbiBhY3Jvc3MgYmF0Y2hlcyIpICsKICBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgY29sb3VyPSJkYXJrcmVkIiwgZ2VvbT0icG9pbnQiLCBzaGFwZT0xOCwgc2l6ZT0zKSAjKwogICNzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgMSkpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBNZWFuIGRpc3BlcnNpb24gb2YgQnJhemlsIGJhdGNoIDEgaXMgcm91Z2hseSAzLjQgdGltZXMgdGhhdCBvZiBJbmRpYS4KKyBUaGUgYWJzb2x1dGUgdmFsdWUgb2YgbWF4IGdlbmUtd2lzZSBkaXNwZXJzaW9uIGFyZSByZWR1Y2VkIGFmdGVyIDAgY291bnRzIGFyZSByZW1vdmVkLgorIEluIHRoaXMgcmVwb3J0LCBkaXNwZXJzaW9uIGFyZSBjYWxjdWxhdGVkIGJ5IGRpZmZlcmVudCBtZXRob2RzIGJlZm9yZSBhbmQgYWZ0ZXIgcmVtb3ZpbmcgMCBjb3VudHMuICoqTm90IGRpcmVjdGx5IGNvbXBhcmFibGUuKioKKyBXZSBzaG93IGluIGFub3RoZXIgYW5hbHlzaXMgKCpUQl9ydW5fbm9uemVyb19kaXNwcy5SKikgdGhhdCAqKnRoZSBkaWZmZXJlbmNlIGluIGRpc3BlcnNpb24gaXMgcmVkdWNlZCBhZnRlciByZW1vdmluZyAwcyoqLgoKCiMjIyBCYXRjaCB2YXJpYW5jZSB3aXRoIDAgY291bnRzIHJlbW92ZWQgCgoqKk1lZGlhbioqIGdlbmUtd2lzZSB2YXJpYW5jZSBhZnRlciByZW1vdmluZyB6ZXJvczogCgpgYGB7ciwgZWNobz1GQUxTRX0KdmFyX3RiX3JtemVybyA8LSBtYXRyaXgoTkEsIG5yb3c9MiwgbmNvbD0zLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChjKCJOb24tcHJvZ3Jlc3NvciIsICJQcm9ncmVzc29yIiksIGMoIkFmcmljYSIsICJHNiIsICJCcmF6aWwxIikpKQpjdHNfcm16ZXJvIDwtIGN0czsgY3RzX3JtemVyb1tjdHNfcm16ZXJvPT0wXSA8LSBOQQp2YXJfdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJBZnJpY2EiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNfcm16ZXJvWywgYmF0Y2g9PSJBZnJpY2EiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiQWZyaWNhIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09IlByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIk5vbi1wcm9ncmVzc29yIiwgIkc2Il0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiRzYiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNfcm16ZXJvWywgYmF0Y2g9PSJHNiImZ3JvdXA9PSJQcm9ncmVzc29yIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQp2YXJfdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJCcmF6aWwxIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQnJhemlsXzEiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiQnJhemlsMSJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c19ybXplcm9bLCBiYXRjaD09IkJyYXppbF8xIiZncm91cD09IlByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnByaW50KHJvdW5kKHZhcl90Yl9ybXplcm8sIDIpKQpgYGAKClNjYWxlZCBieSB0aGF0IG9mIEFmcmljYToKCmBgYHtyLCBlY2hvPUZBTFNFfQp2YXJfdGJfcm16ZXJvX3NjYWxlZCA8LSBhcHBseSh2YXJfdGJfcm16ZXJvLCAyLCBmdW5jdGlvbih4KXt4L3Zhcl90Yl9ybXplcm9bLCJBZnJpY2EiXX0pCnByaW50KHJvdW5kKHZhcl90Yl9ybXplcm9fc2NhbGVkLCAyKSkKYGBgCgoKIyMjIElzIHRoZXJlIGEgZGlmZmVyZW5jZSBpbiB6ZXJvIHBvcnRpb25zIGFjcm9zcyBiYXRjaGVzPwoKQW5vdGhlciBxdWVzdGlvbiByZWxhdGVkIHRvIGJhdGNoIGVmZmVjdCwgaXMgd2hldGhlciB0aGVyZSBpcyBhbnkgZGlmZmVyZW5jZSBpbiB0aGUgcGVyY2VudGFnZSBvZiAwIGNvdW50cyBpbiBhIGdlbmUgYmV0d2VlbiB0d28gYmF0Y2hlcy4gCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kbl96ZXJvc19iYXRjaF9hZnJpY2EgPC0gYXBwbHkoY3RzWywgYmF0Y2g9PSJBZnJpY2EiXSwgMSwgZnVuY3Rpb24oeCl7bGVuZ3RoKHdoaWNoKHg9PTApKX0pCnBlcmNlbnRfemVyb3NfYmF0Y2hfYWZyaWNhIDwtIG5femVyb3NfYmF0Y2hfYWZyaWNhIC8gc3VtKGJhdGNoPT0iQWZyaWNhIikKbl96ZXJvc19iYXRjaF9HNiA8LSBhcHBseShjdHNbLCBiYXRjaD09Ikc2Il0sIDEsIGZ1bmN0aW9uKHgpe2xlbmd0aCh3aGljaCh4PT0wKSl9KQpwZXJjZW50X3plcm9zX2JhdGNoX0c2IDwtIG5femVyb3NfYmF0Y2hfRzYgLyBzdW0oYmF0Y2g9PSJHNiIpCm5femVyb3NfYmF0Y2hfaW5kaWEgPC0gYXBwbHkoY3RzWywgYmF0Y2g9PSJJbmRpYSJdLCAxLCBmdW5jdGlvbih4KXtsZW5ndGgod2hpY2goeD09MCkpfSkKcGVyY2VudF96ZXJvc19iYXRjaF9pbmRpYSA8LSBuX3plcm9zX2JhdGNoX2luZGlhIC8gc3VtKGJhdGNoPT0iSW5kaWEiKQpuX3plcm9zX2JhdGNoX2J6bDEgPC0gYXBwbHkoY3RzWywgYmF0Y2g9PSJCcmF6aWxfMSJdLCAxLCBmdW5jdGlvbih4KXtsZW5ndGgod2hpY2goeD09MCkpfSkKcGVyY2VudF96ZXJvc19iYXRjaF9iemwxIDwtIG5femVyb3NfYmF0Y2hfYnpsMSAvIHN1bShiYXRjaD09IkJyYXppbF8xIikKbl96ZXJvc19iYXRjaF9iemwyIDwtIGFwcGx5KGN0c1ssIGJhdGNoPT0iQnJhemlsXzIiXSwgMSwgZnVuY3Rpb24oeCl7bGVuZ3RoKHdoaWNoKHg9PTApKX0pCnBlcmNlbnRfemVyb3NfYmF0Y2hfYnpsMiA8LSBuX3plcm9zX2JhdGNoX2J6bDIgLyBzdW0oYmF0Y2g9PSJCcmF6aWxfMiIpCgpwZXJjZW50X3plcm9zX2JhdGNoX2RmIDwtIGRhdGEuZnJhbWUoQWZyaWNhPXBlcmNlbnRfemVyb3NfYmF0Y2hfYWZyaWNhLCBHNj1wZXJjZW50X3plcm9zX2JhdGNoX0c2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kaWE9cGVyY2VudF96ZXJvc19iYXRjaF9pbmRpYSwgQnJhemlsXzE9cGVyY2VudF96ZXJvc19iYXRjaF9iemwxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnJhemlsXzI9cGVyY2VudF96ZXJvc19iYXRjaF9iemwyKQpwZXJjZW50X3plcm9zX2JhdGNoX2RmX21sdCA8LSBtZWx0KHBlcmNlbnRfemVyb3NfYmF0Y2hfZGYsIHZhcmlhYmxlLm5hbWU9IkJhdGNoIikKZ2dwbG90KHBlcmNlbnRfemVyb3NfYmF0Y2hfZGZfbWx0LCBhZXMoeD1CYXRjaCwgeT12YWx1ZSkpICsKICBnZW9tX3Zpb2xpbigpICsKICBsYWJzKHk9IlBlcmNlbnRhZ2Ugb2YgMCBjb3VudHMgaW4gYSBzaW5nbGUgZ2VuZSIpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKQpgYGAKCioqQ29uY2x1c2lvbnM6KioKCisgVGhlcmUgaXNuJ3QgYW4gb2J2aW91cyBkaWZmZXJlbmNlIGluIHplcm8gZnJhY3Rpb25zIGJldHdlZW4gYmF0Y2hlcyAoYXNpZGUgZnJvbSBCcmF6aWwgYmF0Y2ggMiB3aGljaCBpcyB0b28gc21hbGwpLgoKCiMjIyBHb29kbmVzcyBvZiBmaXQgZm9yIE5CIGRpc3RyaWJ1dGlvbiB0byBub24temVybyBwb3J0aW9uIG9mIGdlbmVzCgpJdCBpcyBkaWZmaWN1bHQgdG8gZXZhbHVhdGUgcXVhbnRpdGF0aXZlbHkgdGhlIGdvb2RuZXNzLW9mLWZpdCBvZiBOQiBkaXN0cmlidXRpb24gb24gZGF0YS4gSW5zdGVhZCwgd2UgZ2VuZXJhdGUgUS1RIHBsb3RzIGZvciAxMDAgcmFuZG9tbHkgc2VsZWN0ZWQgZ2VuZXMsIGNvbXBhcmluZyBkYXRhIHdpdGggTkIgZGlzdHJpYnV0aW9uIHVzaW5nIE1MIGVzdGltYXRlZCBwYXJhbWV0ZXJzLiBXZSBnZW5lcmF0ZSB0aGVzZSBwbG90cyAqKndpdGhpbiBHNi9BZnJpY2EsIGZvciBjYXNlcyBhbmQgY29udHJvbCBzYW1wbGVzIHNlcGFyYXRlbHkqKi4gRmlndXJlcyBhcmUgc3RvcmVkIHVuZGVyIHtvdXRwdXRfZGlyfS9xcXBsb3RzX3tTdHVkeX0vLgoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUifQppZighZGlyLmV4aXN0cyhmaWxlLnBhdGgob3V0cHV0X2RpciwgInFxcGxvdHNfRzYiKSkpe2Rpci5jcmVhdGUoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJxcXBsb3RzX0c2IikpfQpzZXQuc2VlZCgxMjM0KQpOX3NlbF9uYiA8LSAxMDAKY2hvc2VuX2lkX25iIDwtIHNhbXBsZSgxOm5yb3cocmRzX29iaiksIE5fc2VsX25iLCByZXBsYWNlPUZBTFNFKQpjdHNfc3Vic2V0X25iIDwtIGN0c1tjaG9zZW5faWRfbmIsIF0KZm9yKGkgaW4gMTpOX3NlbF9uYil7CiAgIyBjYXNlIHNhbXBsZXMKICBjdXJyX2N0cyA8LSBjdHNfc3Vic2V0X25iW2ksIGJhdGNoPT0iRzYiICYgZ3JvdXA9PSJQcm9ncmVzc29yIl0KICBjdXJyX2N0cyA8LSBjdXJyX2N0c1tjdXJyX2N0cyE9MF0KICBpZihsZW5ndGgodW5pcXVlKGN1cnJfY3RzKSkgPD0gMyB8IHZhcihjdXJyX2N0cyk9PTApe25leHR9CiAgZGYgPC0gZGF0YS5mcmFtZSh5PWN1cnJfY3RzKQogIHBhcmFtcyA8LSBmaXRkaXN0cihkZiR5LCAibmVnYXRpdmUgYmlub21pYWwiKSRlc3RpbWF0ZQogIAogIHBuZyhwYXN0ZTAob3V0cHV0X2RpciwgIi9xcXBsb3RzX0c2L2dlbmUiLCBpLCAiX2Nhc2VzLnBuZyIpLCAKICAgICAgd2lkdGg9NSwgaGVpZ2h0PTUsIHVuaXRzPSJpbiIsIHJlcz0zMDApCiAgcHJpbnQoZ2dwbG90KGRmLCBhZXMoc2FtcGxlPXkpKSArCiAgICAgICAgICBzdGF0X3FxKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKyAKICAgICAgICAgIHN0YXRfcXFfbGluZShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsKICAgICAgICAgIGxhYnModGl0bGU9IlEtUSBwbG90OiBHNiBQcm9ncmVzc29ycyIpKQogIGRldi5vZmYoKQogIHJtKGN1cnJfY3RzLCBkZiwgcGFyYW1zKQogIAogICMgY29udHJvbCBzYW1wbGVzCiAgY3Vycl9jdHMgPC0gY3RzX3N1YnNldF9uYltpLCBiYXRjaD09Ikc2IiAmIGdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXQogIGN1cnJfY3RzIDwtIGN1cnJfY3RzW2N1cnJfY3RzIT0wXQogIGlmKGxlbmd0aCh1bmlxdWUoY3Vycl9jdHMpKSA8PSAzIHwgdmFyKGN1cnJfY3RzKT09MCl7bmV4dH0KICBkZiA8LSBkYXRhLmZyYW1lKHk9Y3Vycl9jdHMpCiAgcGFyYW1zIDwtIGZpdGRpc3RyKGRmJHksICJuZWdhdGl2ZSBiaW5vbWlhbCIpJGVzdGltYXRlCiAgCiAgcG5nKHBhc3RlMChvdXRwdXRfZGlyLCAiL3FxcGxvdHNfRzYvZ2VuZSIsIGksICJfY29udHJvbHMucG5nIiksIAogICAgICB3aWR0aD01LCBoZWlnaHQ9NSwgdW5pdHM9ImluIiwgcmVzPTMwMCkKICBwcmludChnZ3Bsb3QoZGYsIGFlcyhzYW1wbGU9eSkpICsKICAgICAgICAgIHN0YXRfcXEoZGlzdHJpYnV0aW9uPXFuYmlub20sIGRwYXJhbXM9cGFyYW1zKSArIAogICAgICAgICAgc3RhdF9xcV9saW5lKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKwogICAgICAgICAgbGFicyh0aXRsZT0iUS1RIHBsb3Q6IEc2IE5vbi1wcm9ncmVzc29ycyIpKQogIGRldi5vZmYoKQp9CmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUifQppZighZGlyLmV4aXN0cyhmaWxlLnBhdGgob3V0cHV0X2RpciwgInFxcGxvdHNfYWZyaWNhIikpKXtkaXIuY3JlYXRlKGZpbGUucGF0aChvdXRwdXRfZGlyLCAicXFwbG90c19hZnJpY2EiKSl9CnNldC5zZWVkKDEyMzQpCk5fc2VsX25iIDwtIDEwMApjaG9zZW5faWRfbmIgPC0gc2FtcGxlKDE6bnJvdyhyZHNfb2JqKSwgTl9zZWxfbmIsIHJlcGxhY2U9RkFMU0UpCmN0c19zdWJzZXRfbmIgPC0gY3RzW2Nob3Nlbl9pZF9uYiwgXQpmb3IoaSBpbiAxOk5fc2VsX25iKXsKICAjIGNhc2Ugc2FtcGxlcwogIGN1cnJfY3RzIDwtIGN0c19zdWJzZXRfbmJbaSwgYmF0Y2g9PSJBZnJpY2EiICYgZ3JvdXA9PSJQcm9ncmVzc29yIl0KICBjdXJyX2N0cyA8LSBjdXJyX2N0c1tjdXJyX2N0cyE9MF0KICBpZihsZW5ndGgodW5pcXVlKGN1cnJfY3RzKSkgPD0gMyB8IHZhcihjdXJyX2N0cyk9PTApe25leHR9CiAgZGYgPC0gZGF0YS5mcmFtZSh5PWN1cnJfY3RzKQogIHBhcmFtcyA8LSBmaXRkaXN0cihkZiR5LCAibmVnYXRpdmUgYmlub21pYWwiKSRlc3RpbWF0ZQogIAogIHBuZyhwYXN0ZTAob3V0cHV0X2RpciwgIi9xcXBsb3RzX2FmcmljYS9nZW5lIiwgaSwgIl9jYXNlcy5wbmciKSwgCiAgICAgIHdpZHRoPTUsIGhlaWdodD01LCB1bml0cz0iaW4iLCByZXM9MzAwKQogIHByaW50KGdncGxvdChkZiwgYWVzKHNhbXBsZT15KSkgKwogICAgICAgICAgc3RhdF9xcShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsgCiAgICAgICAgICBzdGF0X3FxX2xpbmUoZGlzdHJpYnV0aW9uPXFuYmlub20sIGRwYXJhbXM9cGFyYW1zKSArCiAgICAgICAgICBsYWJzKHRpdGxlPSJRLVEgcGxvdDogQWZyaWNhIFByb2dyZXNzb3JzIikpCiAgZGV2Lm9mZigpCiAgcm0oY3Vycl9jdHMsIGRmLCBwYXJhbXMpCiAgCiAgIyBjb250cm9sIHNhbXBsZXMKICBjdXJyX2N0cyA8LSBjdHNfc3Vic2V0X25iW2ksIGJhdGNoPT0iQWZyaWNhIiAmIGdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXQogIGN1cnJfY3RzIDwtIGN1cnJfY3RzW2N1cnJfY3RzIT0wXQogIGlmKGxlbmd0aCh1bmlxdWUoY3Vycl9jdHMpKSA8PSAzIHwgdmFyKGN1cnJfY3RzKT09MCl7bmV4dH0KICBkZiA8LSBkYXRhLmZyYW1lKHk9Y3Vycl9jdHMpCiAgcGFyYW1zIDwtIGZpdGRpc3RyKGRmJHksICJuZWdhdGl2ZSBiaW5vbWlhbCIpJGVzdGltYXRlCiAgCiAgcG5nKHBhc3RlMChvdXRwdXRfZGlyLCAiL3FxcGxvdHNfYWZyaWNhL2dlbmUiLCBpLCAiX2NvbnRyb2xzLnBuZyIpLCAKICAgICAgd2lkdGg9NSwgaGVpZ2h0PTUsIHVuaXRzPSJpbiIsIHJlcz0zMDApCiAgcHJpbnQoZ2dwbG90KGRmLCBhZXMoc2FtcGxlPXkpKSArCiAgICAgICAgICBzdGF0X3FxKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKyAKICAgICAgICAgIHN0YXRfcXFfbGluZShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsKICAgICAgICAgIGxhYnModGl0bGU9IlEtUSBwbG90OiBBZnJpY2EgTm9uLXByb2dyZXNzb3JzIikpCiAgZGV2Lm9mZigpCn0KYGBgCgoKIyMgTW9yZSBqdXN0aWZpY2F0aW9uIGZvciBoYXZpbmcgZGlmZmVyZW50IGRpc3BlcnNpb24gcGFyYW1ldGVyIGZvciBkaWZmZXJlbnQgYmF0Y2hlcyAKCkZpbmFsbHksIGEgdmVyeSBpbXBvcnRhbnQgYXNzdW1wdGlvbiBvZiBDb21CYXQtc2VxIG1vZGVsIChjb21wYXJlZCB0byBhZGRpbmcgYmF0Y2ggY292YXJpYXRlcyBpbiBsaW5lYXIgbW9kZWwgb2YgZWRnZVIgYW5kIERFU2VxKSwgaXMgdGhhdCAqKmhhdmluZyBhIGRpZmZlcmVudCBkaXNwZXJzaW9uIHBhcmFtZXRlciBmb3IgZWFjaCBiYXRjaCBpcyBiZW5lZmljaWFsIGZvciBERSBwZXJmb3JtYW5jZS4gQXMgYXJndWVkIGJ5IG1hbnksIGlmIG5vdCBhbGwsIG9mIHRoZXNlIHBhcGVycywgYWNjdXJhdGUgZXN0aW1hdGlvbiBvZiBkaXNwZXJzaW9uIHBhcmFtdGVycyBhcmUgaW1wb3J0YW50IGZvciBERSBkZXRlY3Rpb24qKi4gQXMgd2UgaGF2ZSBzZWVuIGFib3ZlLCB0aGVyZSBpcyBzb21lIGRpZmZlcmVuY2UgaW4gZGlzcGVyc2lvbiBkaXN0cmlidXRpb24gYWNyb3NzIGJhdGNoZXMuIElmIGRpc3BlcnNpb24gZXN0aW1hdGVzIHdpdGhpbiBlYWNoIGJhdGNoIGFuZCB1c2luZyB0aGUgd2hvbGUgc3R1ZHkgYXJlIG5vdCBjb25zaXN0ZW50IHdpdGggZWFjaCBvdGhlciwgdGhlbiBpdCBpcyBqdXN0aWZpY2F0aW9uIHRoYXQgd2UgbWF5IG5lZWQgZGlmZmVyZW50IGRpcHNlcnNpb24gcGFyYW1ldGVyIGZvciBkaWZmZXJlbnQgYmF0Y2hlcywgYW5kIGl0IGNvdWxkIGJlIGdvb2QgZm9yIERFLgoKSGVyZSB3ZSBnZW5lcmF0ZSBzY2F0dGVyIHBsb3RzIGNvbXBhcmluZyBkaXNwZXJzaW9uIGVzdGltYXRlcyB3aXRoaW4gZWFjaCBiYXRjaCB0byBlc3RpbWF0ZXMgZnJvbSB3aG9sZSBkYXRhc2V0ICgqKmluY2x1ZGluZyBiYXRjaCBhcyBhIGNvdmFyaWF0ZSBpbiB3aG9sZSBzdHVkeSoqKS4KCiMjIyBJbiBCcmF6aWwgey50YWJzZXR9CgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CmN0c19icmF6aWwgPC0gY3RzWywgcmRzX29iaiREYXRhc2V0PT0iQnJhemlsIl0KZ3JvdXBfYnJhemlsIDwtIGdyb3VwW3Jkc19vYmokRGF0YXNldD09IkJyYXppbCJdCmJhdGNoX2JyYXppbCA8LSBhcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGJhdGNoW3Jkc19vYmokRGF0YXNldD09IkJyYXppbCJdKSkKCiMjICBEaXNwZXJzaW9uIGluIGJhdGNoZXMgJiBpbiB3aG9sZSBzdHVkeSAoaW5jbHVkaW5nIGJhdGNoIGFzIGNvdmFyaWF0ZSkgKGVkZ2VSKQp5X2JhdGNoMSA8LSBER0VMaXN0KGNvdW50cz1jdHNfYnJhemlsWywgYmF0Y2hfYnJhemlsPT0iQnJhemlsXzEiXSwgCiAgICAgICAgICAgICAgICAgICAgZ3JvdXA9YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cF9icmF6aWxbYmF0Y2hfYnJhemlsPT0iQnJhemlsXzEiXSkpKQp5X2JhdGNoMSA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDEsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoMSA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBfYnJhemlsW2JhdGNoX2JyYXppbD09IkJyYXppbF8xIl0pKSkKeV9iYXRjaDEgPC0gZXN0aW1hdGVEaXNwKHlfYmF0Y2gxLCBkZXNpZ25fYmF0Y2gxKQoKeV9iYXRjaDIgPC0gREdFTGlzdChjb3VudHM9Y3RzX2JyYXppbFssIGJhdGNoX2JyYXppbD09IkJyYXppbF8yIl0pCnlfYmF0Y2gyIDwtIGNhbGNOb3JtRmFjdG9ycyh5X2JhdGNoMiwgbWV0aG9kPSJUTU0iKQpkZXNpZ25fYmF0Y2gyIDwtIE5VTEwKeV9iYXRjaDIgPC0gZXN0aW1hdGVEaXNwKHlfYmF0Y2gyLCBkZXNpZ25fYmF0Y2gyKQoKeV93aG9sZSA8LSBER0VMaXN0KGNvdW50cz1jdHNfYnJhemlsKQp5X3dob2xlIDwtIGNhbGNOb3JtRmFjdG9ycyh5X3dob2xlLCBtZXRob2Q9IlRNTSIpCmRlc2lnbl93aG9sZSA8LSBtb2RlbC5tYXRyaXgofiBncm91cF9icmF6aWwgKyBiYXRjaF9icmF6aWwpCnlfd2hvbGUgPC0gZXN0aW1hdGVEaXNwKHlfd2hvbGUsIGRlc2lnbl93aG9sZSkKCmRpc3AxX2dlbmVfZWRnZVIgPC0geV9iYXRjaDEkdGFnd2lzZS5kaXNwZXJzaW9uCmRpc3AyX2dlbmVfZWRnZVIgPC0geV9iYXRjaDIkdGFnd2lzZS5kaXNwZXJzaW9uCmRpc3BXX2dlbmVfZWRnZVIgPC0geV93aG9sZSR0YWd3aXNlLmRpc3BlcnNpb24KCmRpc3AxX3RyZW5kX2VkZ2VSIDwtIHlfYmF0Y2gxJHRyZW5kZWQuZGlzcGVyc2lvbgpkaXNwMl90cmVuZF9lZGdlUiA8LSB5X2JhdGNoMiR0cmVuZGVkLmRpc3BlcnNpb24KZGlzcFdfdHJlbmRfZWRnZVIgPC0geV93aG9sZSR0cmVuZGVkLmRpc3BlcnNpb24KCgojIyAgRGlzcGVyc2lvbiBpbiBiYXRjaGVzICYgaW4gd2hvbGUgc3R1ZHkgKGluY2x1ZGluZyBiYXRjaCBhcyBjb3ZhcmlhdGUpIChERVNlcTIpCmRkczEgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGE9Y3RzX2JyYXppbFssIGJhdGNoX2JyYXppbD09IkJyYXppbF8xIl0sIGRlc2lnbj1+R3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhPWRhdGEuZnJhbWUoR3JvdXA9YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cF9icmF6aWxbYmF0Y2hfYnJhemlsPT0iQnJhemlsXzEiXSkpKSkKZGRzMSA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkczEpCmRkczEgPC0gZXN0aW1hdGVEaXNwZXJzaW9ucyhkZHMxKQoKZGRzMiA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50RGF0YT1jdHNfYnJhemlsWywgYmF0Y2hfYnJhemlsPT0iQnJhemlsXzIiXSwgZGVzaWduPX4xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YT1kYXRhLmZyYW1lKEdyb3VwPWFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBfYnJhemlsW2JhdGNoX2JyYXppbD09IkJyYXppbF8yIl0pKSkpCmRkczIgPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHMyKQpkZHMyIDwtIGVzdGltYXRlRGlzcGVyc2lvbnMoZGRzMikKCmRkc1cgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGE9Y3RzX2JyYXppbCwgZGVzaWduPX4gR3JvdXAgKyBCYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGE9ZGF0YS5mcmFtZShHcm91cD1ncm91cF9icmF6aWwsIEJhdGNoPWJhdGNoX2JyYXppbCkpCmRkc1cgPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHNXKQpkZHNXIDwtIGVzdGltYXRlRGlzcGVyc2lvbnMoZGRzVykKCmRpc3AxX2dlbmVfREVTZXEyIDwtIGRpc3BlcnNpb25zKGRkczEpCmRpc3AyX2dlbmVfREVTZXEyIDwtIGRpc3BlcnNpb25zKGRkczIpCmRpc3BXX2dlbmVfREVTZXEyIDwtIGRpc3BlcnNpb25zKGRkc1cpCmBgYAoKIyMjIyBHZW5lLXdpc2UgZGlzcGVyc2lvbiBlc3RpbWF0ZXMKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9Nn0KZGlzcHNfYWxsIDwtIGRhdGEuZnJhbWUoQmF0Y2gxLmVkZ2VSPWRpc3AxX2dlbmVfZWRnZVIsIAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDIuZWRnZVI9ZGlzcDJfZ2VuZV9lZGdlUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIFdob2xlLmVkZ2VSPWRpc3BXX2dlbmVfZWRnZVIsCiAgICAgICAgICAgICAgICAgICAgICAgIEJhdGNoMS5lZGdlUi50cmVuZD1kaXNwMV90cmVuZF9lZGdlUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIEJhdGNoMi5lZGdlUi50cmVuZD1kaXNwMl90cmVuZF9lZGdlUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIFdob2xlLmVkZ2VSLnRyZW5kPWRpc3BXX3RyZW5kX2VkZ2VSLAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDEuREVTZXEyPWRpc3AxX2dlbmVfREVTZXEyLCAKICAgICAgICAgICAgICAgICAgICAgICAgQmF0Y2gyLkRFU2VxMj1kaXNwMl9nZW5lX0RFU2VxMiwgCiAgICAgICAgICAgICAgICAgICAgICAgIFdob2xlLkRFU2VxMj1kaXNwV19nZW5lX0RFU2VxMikKZGlzcHNfYWxsX2xvZzEwIDwtIGxvZzEwKGRpc3BzX2FsbCkKCnBsdF9yYW5nZV9lZGdlUiA8LSByYW5nZShjKGRpc3AxX2dlbmVfZWRnZVIsIGRpc3AyX2dlbmVfZWRnZVIsIGRpc3BXX2dlbmVfZWRnZVIpLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZCA8LSByYW5nZShjKGRpc3AxX3RyZW5kX2VkZ2VSLCBkaXNwMl90cmVuZF9lZGdlUiwgZGlzcFdfdHJlbmRfZWRnZVIpLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfREVTZXEyIDwtIHJhbmdlKGMoZGlzcDFfZ2VuZV9ERVNlcTIsIGRpc3AyX2dlbmVfREVTZXEyLCBkaXNwV19nZW5lX0RFU2VxMiksIG5hLnJtPVRSVUUpCgpwbHRfcmFuZ2VfZWRnZVJfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX2VkZ2VSKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCA8LSBsb2cxMChwbHRfcmFuZ2VfZWRnZVJ0cmVuZCkKcGx0X3JhbmdlX0RFU2VxMl9sb2cxMCA8LSBsb2cxMChwbHRfcmFuZ2VfREVTZXEyKQoKZ2VuU2NhdHRlclBsb3QgPC0gZnVuY3Rpb24oZGYsIGFlcy54LCBhZXMueSwgbWV0aG9kLCBwbHQucmFuZ2UpewogIHAgPC0gZ2dwbG90KGRmLCBhZXMoeD1kZlssYWVzLnhdLCB5PWRmWyxhZXMueV0pKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2FibGluZShzbG9wZT0xLCBpbnRlcmNlcHQ9MCwgY29sb3I9ImJsdWUiLCBsaW5ldHlwZT0iZGFzaGVkIikgKwogIGxhYnModGl0bGU9c3ByaW50ZigiJXMsIFBlYXJzb24gY29yciA9ICVzIiwgbWV0aG9kLAogICAgICAgICAgICAgICAgICAgICByb3VuZChjb3IoZGZbLGFlcy54XSwgZGZbLGFlcy55XSwgdXNlPSJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiLCBtZXRob2Q9InBlYXJzb24iKSwyKSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzPXBsdC5yYW5nZSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHM9cGx0LnJhbmdlKQp9CgpwMVdfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIiLCBhZXMueT0iQmF0Y2gxLmVkZ2VSIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKyAKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIikKcDJXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMi5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKcDF2Ml9lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJCYXRjaDEuZWRnZVIiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKIApwMVdfREVTZXEyIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLkRFU2VxMiIsIGFlcy55PSJCYXRjaDEuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJERVNlcTIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX0RFU2VxMl9sb2cxMCkgKyAKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIikKcDJXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gyLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKcDF2Ml9ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLkRFU2VxMiIsIGFlcy55PSJCYXRjaDIuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKCmdyaWQuYXJyYW5nZShwMVdfZWRnZVIsIHAxV19ERVNlcTIsIHAyV19lZGdlUiwgcDJXX0RFU2VxMiwgcDF2Ml9lZGdlUiwgcDF2Ml9ERVNlcTIsIG5yb3c9MywgbmNvbD0yKQpgYGAKCiMjIyMgVHJlbmRlZCBkaXNwZXJzaW9uIGVzdGltYXRlcwoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD02fQpwMVdfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gxLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArIAogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gd2hvbGUgZGF0YXNldCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiKQpwMldfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSB3aG9sZSBkYXRhc2V0IiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMiIpCnAxdjJfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLmVkZ2VSLnRyZW5kIiwgYWVzLnk9IkJhdGNoMi5lZGdlUi50cmVuZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIgdHJlbmQiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKCmdyaWQuYXJyYW5nZShwMVdfZWRnZVIsIHAxV19ERVNlcTIsIHAyV19lZGdlUiwgcDJXX0RFU2VxMiwgcDF2Ml9lZGdlUiwgcDF2Ml9ERVNlcTIsIG5yb3c9MywgbmNvbD0yKQpgYGAKCgojIyMgQWZyaWNhIFZTIEc2IHsudGFic2V0fQoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQpkaXNwc19hbGwgPC0gcmVhZFJEUyhmaWxlLnBhdGgob3V0cHV0X2RpciwgIlRCX2Rpc3BzX0FHLnJkcyIpKQpgYGAKCiMjIyMgR2VuZS13aXNlIGRpc3BlcnNpb24gZXN0aW1hdGVzCgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTZ9CmRpc3BzX2FsbF9sb2cxMCA8LSBsb2cxMChkaXNwc19hbGwpCgpwbHRfcmFuZ2VfZWRnZVIgPC0gcmFuZ2UoZGlzcHNfYWxsWywxOjNdLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZCA8LSByYW5nZShkaXNwc19hbGxbLDQ6Nl0sIG5hLnJtPVRSVUUpCnBsdF9yYW5nZV9ERVNlcTIgPC0gcmFuZ2UoZGlzcHNfYWxsWyw3OjldLCBuYS5ybT1UUlVFKQoKcGx0X3JhbmdlX2VkZ2VSX2xvZzEwIDwtIGxvZzEwKHBsdF9yYW5nZV9lZGdlUikKcGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX2VkZ2VSdHJlbmQpCnBsdF9yYW5nZV9ERVNlcTJfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX0RFU2VxMikKCmdlblNjYXR0ZXJQbG90IDwtIGZ1bmN0aW9uKGRmLCBhZXMueCwgYWVzLnksIG1ldGhvZCwgcGx0LnJhbmdlKXsKICBwIDwtIGdncGxvdChkZiwgYWVzKHg9ZGZbLGFlcy54XSwgeT1kZlssYWVzLnldKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGU9MSwgaW50ZXJjZXB0PTAsIGNvbG9yPSJibHVlIiwgbGluZXR5cGU9ImRhc2hlZCIpICsKICBsYWJzKHRpdGxlPXNwcmludGYoIiVzLCBQZWFyc29uIGNvcnIgPSAlcyIsIG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgcm91bmQoY29yKGRmWyxhZXMueF0sIGRmWyxhZXMueV0sIHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIiwgbWV0aG9kPSJwZWFyc29uIiksMikpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1wbHQucmFuZ2UpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPXBsdC5yYW5nZSkKfQoKcDFXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMS5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsgCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBBZnJpY2EgJiBHNiBtZXJnZWQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBBZnJpY2EiKQpwMldfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gRzYiKQpwMXYyX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9IkJhdGNoMS5lZGdlUiIsIGFlcy55PSJCYXRjaDIuZWRnZVIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gRzYiKQogCnAxV19ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuREVTZXEyIiwgYWVzLnk9IkJhdGNoMS5ERVNlcTIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9IkRFU2VxMiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfREVTZXEyX2xvZzEwKSArIAogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhIikKcDJXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gyLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEFmcmljYSAmIEc2IG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEc2IikKcDF2Ml9ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLkRFU2VxMiIsIGFlcy55PSJCYXRjaDIuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEFmcmljYSIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEc2IikKCmdyaWQuYXJyYW5nZShwMVdfZWRnZVIsIHAxV19ERVNlcTIsIHAyV19lZGdlUiwgcDJXX0RFU2VxMiwgcDF2Ml9lZGdlUiwgcDF2Ml9ERVNlcTIsIG5yb3c9MywgbmNvbD0yKQpgYGAKCiMjIyMgVHJlbmRlZCBkaXNwZXJzaW9uIGVzdGltYXRlcwoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD02fQpwMVdfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gxLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArIAogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhIikKcDJXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSLnRyZW5kIiwgYWVzLnk9IkJhdGNoMi5lZGdlUi50cmVuZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiB0cmVuZCIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gRzYiKQpwMXYyX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9IkJhdGNoMS5lZGdlUi50cmVuZCIsIGFlcy55PSJCYXRjaDIuZWRnZVIudHJlbmQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBBZnJpY2EiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBHNiIpCgpncmlkLmFycmFuZ2UocDFXX2VkZ2VSLCBwMVdfREVTZXEyLCBwMldfZWRnZVIsIHAyV19ERVNlcTIsIHAxdjJfZWRnZVIsIHAxdjJfREVTZXEyLCBucm93PTMsIG5jb2w9MikKYGBgCgojIyMgQnJhemlsIEJhdGNoIDEgVlMgSW5kaWEgey50YWJzZXR9CgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CnJtKGRpc3BzX2FsbCwgZGlzcHNfYWxsX2xvZzEwKQpkaXNwc19hbGwgPC0gcmVhZFJEUyhmaWxlLnBhdGgob3V0cHV0X2RpciwgIlRCX2Rpc3BzX0JJLnJkcyIpKQpgYGAKCiMjIyMgR2VuZS13aXNlIGRpc3BlcnNpb24gZXN0aW1hdGVzCgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTZ9CmRpc3BzX2FsbF9sb2cxMCA8LSBsb2cxMChkaXNwc19hbGwpCgpwbHRfcmFuZ2VfZWRnZVIgPC0gcmFuZ2UoZGlzcHNfYWxsWywxOjNdLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZCA8LSByYW5nZShkaXNwc19hbGxbLDQ6Nl0sIG5hLnJtPVRSVUUpCnBsdF9yYW5nZV9ERVNlcTIgPC0gcmFuZ2UoZGlzcHNfYWxsWyw3OjldLCBuYS5ybT1UUlVFKQoKcGx0X3JhbmdlX2VkZ2VSX2xvZzEwIDwtIGxvZzEwKHBsdF9yYW5nZV9lZGdlUikKcGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX2VkZ2VSdHJlbmQpCnBsdF9yYW5nZV9ERVNlcTJfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX0RFU2VxMikKCmdlblNjYXR0ZXJQbG90IDwtIGZ1bmN0aW9uKGRmLCBhZXMueCwgYWVzLnksIG1ldGhvZCwgcGx0LnJhbmdlKXsKICBwIDwtIGdncGxvdChkZiwgYWVzKHg9ZGZbLGFlcy54XSwgeT1kZlssYWVzLnldKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGU9MSwgaW50ZXJjZXB0PTAsIGNvbG9yPSJibHVlIiwgbGluZXR5cGU9ImRhc2hlZCIpICsKICBsYWJzKHRpdGxlPXNwcmludGYoIiVzLCBQZWFyc29uIGNvcnIgPSAlcyIsIG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgcm91bmQoY29yKGRmWyxhZXMueF0sIGRmWyxhZXMueV0sIHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIiwgbWV0aG9kPSJwZWFyc29uIiksMikpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1wbHQucmFuZ2UpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPXBsdC5yYW5nZSkKfQoKcDFXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMS5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsgCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBCcmF6aWwgMSAmIEluZGlhIG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxIikKcDJXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMi5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxICYgSW5kaWEgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gSW5kaWEiKQpwMXYyX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9IkJhdGNoMS5lZGdlUiIsIGFlcy55PSJCYXRjaDIuZWRnZVIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBJbmRpYSIpCiAKcDFXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gxLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsgCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBCcmF6aWwgMSAmIEluZGlhIG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxIikKcDJXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gyLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxICYgSW5kaWEgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gSW5kaWEiKQpwMXYyX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJCYXRjaDEuREVTZXEyIiwgYWVzLnk9IkJhdGNoMi5ERVNlcTIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJERVNlcTIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX0RFU2VxMl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBJbmRpYSIpCgpncmlkLmFycmFuZ2UocDFXX2VkZ2VSLCBwMVdfREVTZXEyLCBwMldfZWRnZVIsIHAyV19ERVNlcTIsIHAxdjJfZWRnZVIsIHAxdjJfREVTZXEyLCBucm93PTMsIG5jb2w9MikKYGBgCgojIyMjIFRyZW5kZWQgZGlzcGVyc2lvbiBlc3RpbWF0ZXMKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9Nn0KcDFXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSLnRyZW5kIiwgYWVzLnk9IkJhdGNoMS5lZGdlUi50cmVuZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiB0cmVuZCIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCkgKyAKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxICYgSW5kaWEgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiKQpwMldfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBCcmF6aWwgMSAmIEluZGlhIG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEluZGlhIikKcDF2Ml9lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJCYXRjaDEuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiB0cmVuZCIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBJbmRpYSIpCgpncmlkLmFycmFuZ2UocDFXX2VkZ2VSLCBwMVdfREVTZXEyLCBwMldfZWRnZVIsIHAyV19ERVNlcTIsIHAxdjJfZWRnZVIsIHAxdjJfREVTZXEyLCBucm93PTMsIG5jb2w9MikKYGBgCgoKCiMjIFNlc3Npb24gaW5mbyAKCmBgYHtyLCBlY2hvPUZBTFNFfQpzZXNzaW9uSW5mbygpCmBgYAoKCgojIyBSZWZlcmVuY2VzCg==